基于邻接表的图的基本操作(建立,遍历)

图的邻接表表示法类似于树的孩子链表表示法。对于图G中的每个顶点vi ,该方法把所有邻接于vi 的顶点vj 链成一个带头结点的单链表,这个单链表就称为顶点vi 的邻接表(Adjacency List)。

以下代码测试过,为图的邻接表表示方式。

  1. /************************************************************************/  
  2. /* 图的邻接表存储结构                                                    */  
  3. /************************************************************************/  
  4. #include <stdio.h>  
  5. #define MaxVertexNum 100  
  6. #define QueueSize 30   
  7. typedef enum{FALSE,TRUE}Boolean;     
  8. Boolean visited[MaxVertexNum];    
  9. typedef char VertexType;  
  10. typedef int EdgeType;  
  11. typedef struct node     //边表结点  
  12. {  
  13.     int adjvex;         //邻接点域  
  14.     struct node *next;  //域链  
  15.     //若是要表示边上的权,则应增加一个数据域  
  16. }EdgeNode;  
  17. typedef struct vnode    //顶点边结点  
  18. {  
  19.     VertexType vertex;  //顶点域  
  20.     EdgeNode *firstedge;//边表头指针  
  21. }VertexNode;  
  22. typedef VertexNode AdjList[MaxVertexNum];   //AdjList是邻接表类型  
  23. typedef struct   
  24. {  
  25.     AdjList adjlist;    //邻接表  
  26.     int n,e;            //图中当前顶点数和边数  
  27. }ALGraph;               //对于简单的应用,无须定义此类型,可直接使用AdjList类型  
  28. /************************************************************************/  
  29. /* 建立无向图的邻接表算法                                               */  
  30. /************************************************************************/  
  31. void CreateGraphAL (ALGraph *G)     
  32. {     
  33.     int i,j,k;     
  34.     EdgeNode * s;     
  35.     printf(“请输入顶点数和边数(输入格式为:顶点数,边数):/n”);     
  36.     scanf(“%d,%d”,&(G->n),&(G->e));       // 读入顶点数和边数     
  37.     printf(“请输入顶点信息(输入格式为:顶点号<CR>)每个顶点以回车作为结束:/n”);     
  38.     for (i=0;i<G->n;i++)              // 立有n个顶点的顶点表     
  39.     {      
  40.         scanf(“/n%c”,&(G->adjlist[i].vertex)); // 读入顶点信息     
  41.         G->adjlist[i].firstedge=NULL;            // 点的边表头指针设为空     
  42.     }     
  43.     printf(“请输入边的信息(输入格式为:i,j):/n”);     
  44.     for (k=0;k<G->e;k++)      // 建立边表     
  45.     {      
  46.         scanf(“/n%d,%d”,&i,&j); // 读入边<Vi,Vj>的顶点对应序号     
  47.         s=new EdgeNode;         // 生成新边表结点s     
  48.         s->adjvex=j;         // 邻接点序号为j     
  49.         s->next=G->adjlist[i].firstedge; // 将新边表结点s插入到顶点Vi的边表头部     
  50.         G->adjlist[i].firstedge=s;     
  51.         s=new EdgeNode;  
  52.         s->adjvex=i;  
  53.         s->next=G->adjlist[j].firstedge;  
  54.         G->adjlist[j].firstedge=s;  
  55.     }     
  56. }    
  57. /************************************************************************/  
  58. /* 深度优先遍历                                                         */  
  59. /************************************************************************/   
  60. void DFS(ALGraph *G,int i)  
  61. {   
  62.     //以vi为出发点对邻接表表示的图G进行深度优先搜索  
  63.     EdgeNode *p;  
  64.     printf(“visit vertex:%c/n”,G->adjlist[i].vertex);  // 访问顶点vi  
  65.     visited[i]=TRUE;                //标记vi已访问  
  66.     p=G->adjlist[i].firstedge;       //取vi边表的头指针  
  67.     while(p)  
  68.     {                               //依次搜索vi的邻接点vj,这里j=p->adjvex  
  69.         if (!visited[p->adjvex]) //若vi尚未被访问  
  70.             DFS(G,p->adjvex);        //则以Vj为出发点向纵深搜索  
  71.         p=p->next;                    //找vi的下一邻接点  
  72.     }  
  73. }  
  74. void DFSTraverseM(ALGraph *G)     
  75. {     
  76.     int i;     
  77.     for(i=0;i<G->n;i++)     
  78.         visited[i]=FALSE;        
  79.     for(i=0;i<G->n;i++)     
  80.         if(!visited[i])      
  81.             DFS(G,i);     
  82. }   
  83. /************************************************************************/  
  84. /* 广度优先遍历                                                         */  
  85. /************************************************************************/  
  86. typedef struct    
  87. {     
  88.     int front;     
  89.     int rear;     
  90.     int count;     
  91.     int data[QueueSize];     
  92. }CirQueue;     
  93. void InitQueue(CirQueue *Q)     
  94. {     
  95.     Q->front=Q->rear=0;     
  96.     Q->count=0;     
  97. }     
  98. int QueueEmpty(CirQueue *Q)     
  99. {     
  100.     return Q->count=QueueSize;     
  101. }     
  102. int QueueFull(CirQueue *Q)     
  103. {     
  104.     return Q->count==QueueSize;     
  105. }     
  106. void EnQueue(CirQueue *Q,int x)     
  107. {      
  108.     if (QueueFull(Q))     
  109.         printf(“Queue overflow”);     
  110.     else    
  111.     {      
  112.         Q->count++;     
  113.         Q->data[Q->rear]=x;     
  114.         Q->rear=(Q->rear+1)%QueueSize;     
  115.     }     
  116. }     
  117. int DeQueue(CirQueue *Q)     
  118. {     
  119.     int temp;     
  120.     if(QueueEmpty(Q))     
  121.     {      
  122.         printf(“Queue underflow”);     
  123.         return NULL;     
  124.     }     
  125.     else    
  126.     {     
  127.         temp=Q->data[Q->front];     
  128.         Q->count–;     
  129.         Q->front=(Q->front+1)%QueueSize;     
  130.         return temp;     
  131.     }     
  132. }     
  133. void BFS(ALGraph*G,int k)  
  134. {   // 以vk为源点对用邻接表表示的图G进行广度优先搜索  
  135.     int i;  
  136.     CirQueue Q;             //须将队列定义中DataType改为int  
  137.     EdgeNode *p;  
  138.     InitQueue(&Q);          //队列初始化  
  139.     printf(“visit vertex:%c/n”,G->adjlist[k].vertex);        //访问源点vk  
  140.         visited[k]=TRUE;   
  141.     EnQueue(&Q,k);          //vk已访问,将其人队。(实际上是将其序号人队)  
  142.     while(!QueueEmpty(&Q))  
  143.     {                                   //队非空则执行  
  144.         i=DeQueue(&Q);                  //相当于vi出队  
  145.         p=G->adjlist[i].firstedge;       //取vi的边表头指针  
  146.         while(p)  
  147.         {                               //依次搜索vi的邻接点vj(令p->adjvex=j)  
  148.             if(!visited[p->adjvex])  
  149.             {                           //若vj未访问过  
  150.                 printf(“visit vertex:%c”,G->adjlist[p->adjvex].vertex);       //访问vj  
  151.                 visited[p->adjvex]=TRUE;   
  152.                 EnQueue(&Q,p->adjvex);   //访问过的vj人队  
  153.             }  
  154.             p=p->next;                   //找vi的下一邻接点  
  155.         }  
  156.     }  
  157. }  
  158. void BFSTraverseM(ALGraph *G)     
  159. {     
  160.     int i;     
  161.     for (i=0;i<G->n;i++)     
  162.         visited[i]=FALSE;     
  163.     for (i=0;i<G->n;i++)     
  164.         if (!visited[i])      
  165.             BFS(G,i);     
  166. }     
  167. /************************************************************************/  
  168. /* 主函数调用                                                           */  
  169. /************************************************************************/  
  170. int main()  
  171. {  
  172.     ALGraph G;  
  173.     CreateGraphAL(&G);  
  174.     printf(“深度优先遍历:/n”);  
  175.     DFSTraverseM(&G);  
  176.     printf(“广度优先遍历:/n”);  
  177.     BFSTraverseM(&G);  
  178.     return 0;  
  179. }  
    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/cherish_xmm/article/details/41787383
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞