图的邻接表存储结构及求各顶点的度

数组与链表相结合的存储方法称为邻接表(Adjacency List)

邻接表的处理方法是:

1.图中顶点用一个一维数组存储,当然,顶点也可以用单链表来存储,不过数组可以较容易地读取顶点信息,更加方便。另外,对于顶点数组中,每个数组元素还需要存储指向第一个邻接点的指针,以便于查找该顶点的边信息。

2.图中每个顶点Vi的所有邻接点构成一个线性表,由于邻接点的个数不定,所以用单链表存储,无向图称为顶点Vi的边表,有向图称为顶点Vi作为弧尾的出边表。


获取图的相关信息:

1.我们要想知道某个顶点的度,就去查找这个顶点的边表中节点的个数。

2.要判断顶点Vi到Vj是否存在边,只需要测试顶点Vi的边表中adjvex是否存在节点Vj的下标j就行了。

3.求顶点的所有邻接点,其实就是对此顶点的边表进行遍历,得到的adjvex域对应的顶点就是邻接点。


对于有向图,邻接表是以顶点为弧尾来存储边表的,逆邻接表是以顶点为弧头来存储边表的。


无向图的邻接表结构:图的邻接表存储结构及求各顶点的度


有向图的邻接表及逆邻接表结构:图的邻接表存储结构及求各顶点的度


对于带权的网图,可以在边表节点定义中再增加一个weight的数据域,存储权值信息即可:

图的邻接表存储结构及求各顶点的度


下面的程序就是利用图的邻接表存储结构,实现计算无向图的各个顶点的度数(C/C++):


/*********************************************/

/*    邻接表存储结构      */

/*********************************************/

#include <stdio.h>

#include <stdlib.h>

#include <iostream>

using namespace std;


#define M 20            //预定义图的最大顶点数


typedef char DataType; //顶点信息数据类型


typedef struct node{      //边表结点

    int adjvex;      //邻接点

    struct node *next;

}EdgeNode;


typedef struct vnode{     //头结点类型

    DataType vertex;         //顶点信息

    EdgeNode *FirstEdge;  //邻接链表头指针

}VertexNode;


typedef struct{          //邻接表类型

    VertexNode adjlist[M]; //存放头结点的顺序表

    int n,e;                 //图的顶点数与边数

}LinkedGraph;


/*

 函数功能:建立图的邻接表

 函数参数:邻接表指针变量g;

 存放图信息的文件名filename;

 图的类型参数c,c=0表示建立无向图,否则表示建立有向图

 函数返回值:无

 */


void creat(LinkedGraph *g,char *filename,int c)

{

    int i,j,k;

    EdgeNode *s;

    FILE *fp;

    fp=fopen(filename,"r");

    if (fp)

    {

        fscanf(fp,"%d%d",&g->n,&g->e);             //读入顶点数与边数

        

        for(i=0;i<g->n;i++)

        {

            fscanf(fp,"%1s",&g->adjlist[i].vertex);   //读入顶点信息

            g->adjlist[i].FirstEdge=NULL;        //边表置为空表

        }

        

        for(k=0;k<g->e;k++)                    //循环e次建立边表

        {

            fscanf(fp,"%d%d",&i,&j);                // 输入无序对(i,j)

            s=(EdgeNode *)malloc(sizeof(EdgeNode));

            s->adjvex=j;                        //邻接点序号为j

            s->next=g->adjlist[i].FirstEdge;

            g->adjlist[i].FirstEdge=s;         //将新结点*s插入顶点vi的边表头部

            if (c==0)                           //无向图

            {

                s=(EdgeNode *)malloc(sizeof(EdgeNode));

                s->adjvex=i;                        //邻接点序号为i

                s->next=g->adjlist[j].FirstEdge;

                g->adjlist[j].FirstEdge=s;     //将新结点*s插入顶点vj的边表头部

            }

        }

        fclose(fp);

    }

    else

        g->n=0;

}


//函数print():输出邻接表存储结构

void print(LinkedGraph g)

{

    EdgeNode *p;

    int i;

    for (i=0;i<g.n;i++)

    {

        printf("%c",g.adjlist[i].vertex);

        p=g.adjlist[i].FirstEdge;

        while (p)

        {

            printf("-->%d",p->adjvex);

            p=p->next;

        }

        printf("\n");

    }

}


//函数weight():输出无向图各顶点的度数

void weight(LinkedGraph g)

{

    EdgeNode *p;

    int n,i;

    for (i=0;i<g.n;i++)

    {

        n=0;

        p=g.adjlist[i].FirstEdge;

        while (p)

        {

            n++;

            p=p->next;

        }

        cout<<i<<":"<<n<<endl;

        //printf("%d:%d\n",i,n);

    }

}


int main()

{

    LinkedGraph * Grap=newLinkedGraph;

    creat(Grap,"G11.TXT",0);

    print(*Grap);

    weight(*Grap);

    delete Grap;

    /*

    LinkedGraph g;

    creat(&g,"G11.TXT",0);

    print(g);

    weight(g);

     */

    return 0;

}