leiyahui

纸上得来终觉浅,绝知此事要躬行
图的存储结构

一 图的数组表示

图的数组表示就是使用两个数组,一个一维数组一个二维数组,一维数组表示图中的节点,二维数组表示图中节点的关系解R

二维数组中a[i][j]表示节点i和节点j之间的关系,1表示两个节点是连通的,0表示两个节点是不相连接的。

对于无向图来说因为(vi,vj)belongs R则(vj,vi) belongs R所以说无向图的邻接矩阵是对称矩阵。

对于网来说需要表示权值,所以说可以使用以下的表示方法;

如果vi和vj是连通的话,a[i][j]=w

否则的话a[i][j]=正无穷

下面是无向网建立数组表示法的算法实现

#include <stdio.h>
#include <stdlib.h>
#define maxsize 64
typedef struct Node
{
    char data[maxsize];        //存储节点数据
    int Rdata[maxsize][maxsize];        //存储权值
}graphNode;
void Createmgraph(graphNode* G)
{
    int i, j, n;
    char nodeF, nodeL;
    int w;
    char ch;
    n = 0;
    printf("%d", n);
    ch = getchar();
    getchar();
    printf("\n");
    while (ch != '#')        //将节点读进一维数组中
    {
        G->data[n] = ch;
        n++;
        if (n == 64)
        {
            break;    //超出存储空间之后,溢出处理
            printf("溢出");
        }
        printf("%d",n);
        ch = getchar();
        getchar();
        printf("\n");
    }
    for (i = 0; i<n; i++)
    {
        for (j = 0; j<n; j++)
        {
            G->Rdata[i][j] = 1000000;        //将节点初始化为正无穷
        }
    }
    printf("Please input the R\n");
    scanf_s("%c %c %d", &nodeF, &nodeL, &w);
        while (nodeF!= '#')
        {
            for (i = 0; i<n; i++)        //求初始节点的位置
            {
                if (G->data[i] == nodeF)
                {
                    break;
                }
            }
            for (j = 0; j<n; j++)        //求第二个节点的位置
            {
                if (G->data[j] == nodeL)
                {
                    break;
                }
            }
            G->Rdata[i][j] = w;
            G->Rdata[j][i] = w;
            scanf_s("%c,%c,%d", &nodeF, &nodeL, &w);
        }
}
void main()
{
    graphNode* G=(graphNode*)malloc(sizeof(graphNode));
    printf("Please input node\n");
    Createmgraph(G);
}

二 邻接表表示法

邻接表是一种链式存储结构,有点类似于树中的孩子链表示法,这种表示方法将所以的节点存储在一个数组中,然后将从节点I出发的弧构成单链表

下面是算法实现:

#include <stdlib.h>
#include <stdio.h>
#define Maxn 100
typedef struct Node
{
    int adj;        //邻接节点域
    int w;            //权值
    Node* next;        //下一个邻接节点
}linkNode,*linkList;
typedef struct vNode        //顶点数据类型
{
    char data;        //存放数据,暂且定为char
    linkList list;        //存放第一个节点的地址
}VNode;
void Createadj(VNode G[], int n)        //总共有n个节点
{
    int i, j;
    linkList p, q;
    char ch;
    char a, b;
    int c;
    scanf_s("%c", &ch);
    for (i = 0; i<n; i++)        //将数据读进数组
    {
        G[i].data = ch;
        G[i].list = NULL;
        scanf_s("%c", &ch);
        i++;
        getchar();        //消除缓冲区的‘\n’
    }
    scanf("%c,%c,%d", &a, &b, &c);
    while (a != '#')
    {
        for (i = 0; i<n; i++)
        {
            if (a == G[i].data)
            {
                break;
            }
        }
        for (j = 0; j<n; j++)
        {
            if (b == G[j].data)
            {
                break;
            }
        }
        p = (linkList)malloc(sizeof(linkNode));
        p->adj = j;
        p->w = c;
        p->next = NULL;
        q = G[i].list;
        while (q != NULL)        //建立i到j的连接
        {
            q = q->next;
        }
        q = p;
        p->adj = i;
        q = G[j].list;
        while (q != NULL)            //根据无向表的对称性建立
        {
            q = q->next;
        }
        q = p;
        scanf_s("%c,%c,%d", &a, &b, &c);
    }
}

三 十字链表示法

十字链表示法是邻接表和逆邻接表的结合,这种方式更容易求出有向图的入读和出度。

posted on 2015-12-20 10:45  雷大叔  阅读(140)  评论(0)    收藏  举报