图论(6)--邻接表的建立与入度出度

来源:互联网 发布:数据采集卡的作用 编辑:程序博客网 时间:2024/06/06 04:28

邻接表是图的一种链式存储结构
在邻接表中,对图中每个顶点建立一个单链表,第i个单链表中的结点表示依附于顶点Vi的边(对有向图来说,是以顶点Vi为尾的弧)

邻接表的存储表示

每个结点由3个域组成
邻接点域(adjvex):与顶点Vi邻接的点在图中的位置
链域(nextarc):下一条边或弧的结点
数据域(firstarc):与边或弧相关的信息

#define INFINITY INT_MAX#define MAX_VERTEX_NUM 20//最大顶点个数typedef char VertexType;typedef int status;//邻接表的相关定义typedef struct ArcNode{    VertexType adjvex;      //该弧所指向的顶点的位置    struct ArcNode *nextarc;//指向下一条弧的指针}ArcNode;                   //表结点typedef struct VNode{    VertexType data;        //顶点信息    ArcNode *firstarc;      //指向第一条依附该顶点的弧的指针}VNode,AdjList[MAX_VERTEX_NUM];                            //头结点typedef struct{    AdjList vertices;           int vexnum,arcnum;      //图的当前顶点数和弧数    int kind;               //图的种类标志}ALGraph;

构造邻接表

//用邻接表构造有向图或无向图status CreateGraph2(ALGraph &P){ int i; int kind; char c; ArcNode *q,*j;             //构造两个表结点 printf("请选择:1:建立有向图;2:建立无向图\n");  scanf("%d",&kind); if(kind==1)  P.kind=1; else if(kind==2)  P.kind=0; else {printf("输入错误!\n"); return OVERFLOW;} printf("请输入顶点个数:\n");  scanf("%d",&P.vexnum);    //P.exnum为顶点个数 printf("请依次输入%d个顶点\n",P.vexnum); getchar(); for(i=0;i<P.vexnum;i++)  scanf("%c",&P.vertices[i].data);  //构造头结点数组 存储每一个头结点(顶点)的data for(i=0;i<P.vexnum;i++) { printf("请输入第%d个顶点即%c指向的第一个结点,以#表示空:\n",i+1,P.vertices[i].data);  getchar();  scanf("%c",&c);  q=(ArcNode*)malloc(sizeof(ArcNode));      //开辟头结点(顶点)链表空间  if(c!='#')  { q->adjvex=c;                            //头结点指向的第一个元素   q->nextarc=NULL;                         //指向下一条弧的指针为空   P.vertices[i].firstarc=q;                //头结点指向该顶点的表结点   printf("请继续输入第%d个顶点后面的结点,以#表示结束:\n",i+1);   getchar();   scanf("%c",&c);   j=(ArcNode*)malloc(sizeof(ArcNode));   q=P.vertices[i].firstarc;                //q指向第一个顶点后的第一个结点   while(c!='#')   {    j->adjvex=c;    j->nextarc=NULL;                        //将后续结点储存在j中    q->nextarc=j;                           //q即第一个顶点后的第一个结点指向后续结点    q=q->nextarc;                           //q后移    scanf("%c",&c);   }   q->nextarc=NULL;}  else   P.vertices[i].firstarc=NULL; } return OK;}//

入度出度函数

//利用邻接表求有向图和无向图的顶点的度status vexdu2(ALGraph &P){ int i,j,k,v1[100],v2[100]; ArcNode *q; if(P.kind==0)                          //无向图 {for(i=0;i<P.vexnum;i++)  {k=0;   if(P.vertices[i].firstarc==NULL)   k=0;      else   {k=1;                                //指的是表结点中有第一个节点    q=P.vertices[i].firstarc;           //q指向表结点中第一个结点    while(q->nextarc!=NULL)    {k++;     q=q->nextarc;    }   }  printf("第%d个顶点即%c的度是%d\n",i+1,P.vertices[i].data,k);  } } else if(P.kind==1)                     //有向图 {for(i=0;i<P.vexnum;i++)  {v1[i]=0;    if(P.vertices[i].firstarc==NULL)   v1[i]=0;      else   {v1[i]=1;    q=P.vertices[i].firstarc;    while(q->nextarc!=NULL)    {v1[i]++;     q=q->nextarc;                       //v1为出度    }   }  }  for(i=0;i<P.vexnum;i++)  v2[i]=0;  for(i=0;i<P.vexnum;i++)  {  if(P.vertices[i].firstarc!=NULL)   for(j=0;j<P.vexnum;j++)    if(P.vertices[i].firstarc->adjvex==P.vertices[j].data)     v2[j]++; }//检验表结点第一个结点与头结点的关系  for(i=0;i<P.vexnum;i++)  { q=P.vertices[i].firstarc;  if(q!=NULL)  while(q->nextarc!=NULL)   {    for(j=0;j<P.vexnum;j++)     if(P.vertices[j].data==q->nextarc->adjvex)      v2[j]++;    q=q->nextarc;   }  }//检验表结点中其他结点与头结点的关系  for(i=0;i<P.vexnum;i++)  printf("第%d个顶点即%c的出度是%d,入度是%d\n",i+1,P.vertices[i].data,v1[i],v2[i]); } return OK;}//

完整代码

#include<stdio.h>#include<stdlib.h>#define OK 1#define ERROR 0#define OVERFLOW -2#define INFINITY INT_MAX#define MAX_VERTEX_NUM 20//最大顶点个数typedef char VertexType;typedef int status;//邻接表的相关定义typedef struct ArcNode{ VertexType adjvex;  //该弧所指向的顶点的位置 struct ArcNode *nextarc;//指向下一条弧的指针}ArcNode;typedef struct VNode{ VertexType data;  //顶点信息 ArcNode *firstarc;  //指向第一条依附该顶点的弧的指针}VNode,AdjList[MAX_VERTEX_NUM];typedef struct{ AdjList vertices;   int vexnum,arcnum;  //图的当前顶点数和弧数 int kind;   //图的种类标志}ALGraph;//用邻接表构造有向图或无向图status CreateGraph2(ALGraph &P){ int i; int kind; char c; ArcNode *q,*j; printf("请选择:1:建立有向图;2:建立无向图\n");  scanf("%d",&kind); if(kind==1)  P.kind=1; else if(kind==2)  P.kind=0; else {printf("输入错误!\n"); return OVERFLOW;} printf("请输入顶点个数:\n");  scanf("%d",&P.vexnum); printf("请依次输入%d个顶点\n",P.vexnum); getchar(); for(i=0;i<P.vexnum;i++)  scanf("%c",&P.vertices[i].data); for(i=0;i<P.vexnum;i++) { printf("请输入第%d个顶点即%c指向的第一个结点,以#表示空:\n",i+1,P.vertices[i].data);  getchar();  scanf("%c",&c);  q=(ArcNode*)malloc(sizeof(ArcNode));  if(c!='#')  { q->adjvex=c;   q->nextarc=NULL;   P.vertices[i].firstarc=q;   printf("请继续输入第%d个顶点后面的结点,以#表示结束:\n",i+1);   getchar();   scanf("%c",&c);   j=(ArcNode*)malloc(sizeof(ArcNode));   q=P.vertices[i].firstarc;   while(c!='#')   {     j=(ArcNode*)malloc(sizeof(ArcNode));    j->adjvex=c;    j->nextarc=NULL;    q->nextarc=j;    q=q->nextarc;    scanf("%c",&c);   }   q->nextarc=NULL;}  else   P.vertices[i].firstarc=NULL; } return OK;}////利用邻接表求有向图和无向图的顶点的度status vexdu2(ALGraph &P){ int i,j,k,v1[100],v2[100]; ArcNode *q; if(P.kind==0) {for(i=0;i<P.vexnum;i++)  {k=0;   if(P.vertices[i].firstarc==NULL)   k=0;      else   {k=1;    q=P.vertices[i].firstarc;    while(q->nextarc!=NULL)    {k++;     q=q->nextarc;    }   }  printf("第%d个顶点即%c的度是%d\n",i+1,P.vertices[i].data,k);  } } else if(P.kind==1) {for(i=0;i<P.vexnum;i++)  {v1[i]=0;    if(P.vertices[i].firstarc==NULL)   v1[i]=0;      else   {v1[i]=1;    q=P.vertices[i].firstarc;    while(q->nextarc!=NULL)    {v1[i]++;     q=q->nextarc;    }   }  }  for(i=0;i<P.vexnum;i++)  v2[i]=0;  for(i=0;i<P.vexnum;i++)  {   if(P.vertices[i].firstarc!=NULL)   for(j=0;j<P.vexnum;j++)    if(P.vertices[i].firstarc->adjvex==P.vertices[j].data)     v2[j]++; }  for(i=0;i<P.vexnum;i++)  { q=P.vertices[i].firstarc;  if(q!=NULL)  while(q->nextarc!=NULL)    {    for(j=0;j<P.vexnum;j++)     if(P.vertices[j].data==q->nextarc->adjvex)      v2[j]++;    q=q->nextarc;   }  }  for(i=0;i<P.vexnum;i++)  printf("第%d个顶点即%c的出度是%d,入度是%d\n",i+1,P.vertices[i].data,v1[i],v2[i]);  } return OK;}////主函数int main(){ ALGraph P; CreateGraph2(P); vexdu2(P); return 0;}
0 0
原创粉丝点击