第十二周项目2-操作用邻接表存储的图

  1. /* 
  2.  
  3. copyright (t) 2016,烟台大学计算机学院 
  4.  
  5. *All rights reserved. 
  6.  
  7. *文件名称:1.cpp 
  8.  
  9. *作者:车金阳
  10.  
  11. *完成日期:2016年12月15日 
  12.  
  13. *版本号:v1.0 
  14.  
  15. *问题描述:假设图G采用邻接表存储,分别设计实现以下要求的算法:  
  16.     (1)输出出图G中每个顶点的出度;  
  17.     (2)求出图G中出度最大的一个顶点,输出该顶点编号;  
  18.     (3)计算图G中出度为0的顶点数;  
  19.     (4)判断图G中是否存在边<i,j>。  
  20.     利用下图作为测试用图(见知识点总结部分),输出结果。  
  21.     提示:(1)分别设计函数实现算法;(2)不要全部实现完再测试,而是实现一个,测试一个;(3)请利用图算法库。 
  22.  
  23. *输入描述:无 
  24.  
  25. *程序输出:测试结果 
  26.  
  27. */  

graph.h:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #define MAXV 100                   //定义最大顶点数100  
  3. #define limitless 9999             //处理“无穷大”  
  4. typedef int InfoType;              //定义顶点与边的相关信息  
  5. typedef int Vertex;  
  6.   
  7. typedef struct                     //定义顶点类型  
  8. {  
  9.     int no;                        //顶点编号  
  10.     InfoType info;                 //顶点其他信息  
  11. } VertexType;  
  12. typedef struct                     //定义图邻接矩阵类型  
  13. {  
  14.     int edges[MAXV][MAXV];         //邻接矩阵边数组  
  15.     int n;                         //顶点数  
  16.     int e;                         //边数  
  17.     VertexType vexs[MAXV];         //存放顶点信息  
  18. } MGraph;  
  19.   
  20. typedef struct ANode               //定义边节点类型  
  21. {  
  22.     int adjvex;                    //该边终点编号  
  23.     struct ANode *nextarc;         //指向下一条边的指针  
  24.     InfoType info;                 //该边相关信息  
  25. } ArcNode;  
  26. typedef struct VNode               //定义邻接表头节点类型  
  27. {  
  28.     Vertex data;                   //顶点信息  
  29.     ArcNode *firstarc;             //指向第一条边的指针  
  30. } VNode;  
  31. typedef VNode AdjList[MAXV];       //AdjList: 邻接表类型  
  32. typedef struct                     //定义图邻接表类型  
  33. {  
  34.     AdjList adjlist;               //邻接表  
  35.     int n;                         //图中顶点数  
  36.     int e;                         //图中边数  
  37. } ALGraph;  
  38.   
  39. void ArrayToMat(int *Arr, int n, MGraph &g);         //用普通数组构造图的邻接矩阵  
  40. void ArrayToList(int *Arr, int n, ALGraph *&G);      //用普通数组构造图的邻接表  
  41. void MatToList(MGraph g,ALGraph *&G);                //将邻接矩阵g转换成邻接表G  
  42. void ListToMat(ALGraph *G,MGraph &g);                //将邻接表G转换成邻接矩阵g  
  43. void DispMat(MGraph g);                              //输出邻接矩阵g  
  44. void DispAdj(ALGraph *G);                            //输出邻接表G  

graph.cpp:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <malloc.h>  
  2. #include "graph.h"  
  3. //几点说明:  
  4. //功能:由一个反映图中顶点邻接关系的二维数组,构造出用邻接矩阵存储的图  
  5. //参数:Arr - 数组名,由于形式参数为二维数组时必须给出每行的元素个数,在此将参数Arr声明为一维数组名(指向int的指针)  
  6. //      n - 矩阵的阶数  
  7. //      g - 要构造出来的邻接矩阵数据结构  
  8. void ArrayToMat(int *Arr, int n, MGraph &g)         //用普通数组构造图的邻接矩阵  
  9. {  
  10.     int i,j;  
  11.     int edgenum=0;                                  //边数初始化为0  
  12.     g.n=n;  
  13.     for(i=0;i<g.n;i++)  
  14.     {  
  15.         for(j=0;j<g.n;j++)  
  16.         {  
  17.             g.edges[i][j]=Arr[i*n+j];               //计算存储位置  
  18.             if(g.edges[i][j]!=0 && g.edges[i][j]!=limitless)  
  19.                 edgenum++;  
  20.         }  
  21.     }  
  22.     g.e=edgenum;  
  23. }  
  24. void ArrayToList(int *Arr, int n, ALGraph *&G)      //用普通数组构造图的邻接表  
  25. {  
  26.     int i,j;  
  27.     int edgenum=0;                                  //边数初始化为0  
  28.     ArcNode *p;                                     //后续操作中创建的新节点  
  29.     G=(ALGraph *)malloc(sizeof(ALGraph));  
  30.     G->n=n;  
  31.     for(i=0;i<n;i++)                                //邻接表所有头节点指针域置初值  
  32.         G->adjlist[i].firstarc=NULL;  
  33.     for(i=0;i<n;i++)                                //遍历邻接矩阵中的每个元素  
  34.     {  
  35.         for(j=n-1;j>=0;j--)  
  36.         {  
  37.             if(Arr[i*n+j]!=0)  
  38.             {  
  39.                 p=(ArcNode *)malloc(sizeof(ArcNode)); //创建节点*p  
  40.                 p->adjvex=j;  
  41.                 p->info=Arr[i*n+j];  
  42.                 p->nextarc=G->adjlist[i].firstarc;    //头插法插入*p  
  43.                 G->adjlist[i].firstarc=p;             //指向第一条边的指针指向*p  
  44.             }  
  45.         }  
  46.     }  
  47.     G->e=edgenum;  
  48. }  
  49. void MatToList(MGraph g,ALGraph *&G)                //将邻接矩阵g转换成邻接表G  
  50. {  
  51.     int i,j;  
  52.     ArcNode *p;  
  53.     G=(ALGraph *)malloc(sizeof(ALGraph));  
  54.     for(i=0;i<g.n;i++)                              //给邻接表所有头节点的指针域置初值  
  55.         G->adjlist[i].firstarc=NULL;  
  56.     for(i=0;i<g.n;i++)                              //遍历邻接矩阵中的每个元素  
  57.     {  
  58.         for(j=g.n-1;j>=0;j--)  
  59.         {  
  60.             if(g.edges[i][j]!=0)  
  61.             {  
  62.                 p=(ArcNode *)malloc(sizeof(ArcNode)); //创建一个节点*p  
  63.                 p->adjvex=j;                          //终点编号赋值  
  64.                 p->nextarc=G->adjlist[i].firstarc;    //头插法插入节点*p  
  65.                 G->adjlist[i].firstarc=p;             //连接  
  66.             }  
  67.         }  
  68.     }  
  69.     G->n=g.n;  
  70.     G->e=g.e;  
  71. }  
  72. void ListToMat(ALGraph *G,MGraph &g)                //将邻接表G转换成邻接矩阵g  
  73. {  
  74.     //前提要求:g的实参调用前已经初始化为全0  
  75.     int i;  
  76.     ArcNode *p;  
  77.     for(i=0;i<G->n;i++)  
  78.     {  
  79.         p=G->adjlist[i].firstarc;                   //*p指向每个顶点的第一条边  
  80.         while(p!=NULL)                              //依次遍历  
  81.         {  
  82.             g.edges[i][p->adjvex]=1;                //p不为空指针时对应矩阵元素赋值1  
  83.             p=p->nextarc;                           //*p指向下一条边  
  84.         }  
  85.     }  
  86.     g.n=G->n;  
  87.     g.e=G->e;  
  88. }  
  89. void DispMat(MGraph g)                              //输出邻接矩阵g  
  90. {  
  91.     int i,j;  
  92.     for(i=0;i<g.n;i++)  
  93.     {  
  94.         for(j=0;j<g.n;j++)  
  95.             if(g.edges[i][j]==limitless)  
  96.                 printf("%3s","∞");  
  97.             else  
  98.                 printf("%3d",g.edges[i][j]);  
  99.         printf("\n");  
  100.     }  
  101. }  
  102. void DispAdj(ALGraph *G)                            //输出邻接表G  
  103. {  
  104.     int i;  
  105.     ArcNode *p;  
  106.     for (i=0; i<G->n; i++)  
  107.     {  
  108.         p=G->adjlist[i].firstarc;  
  109.         printf("%3d: ",i);  
  110.         while (p!=NULL)  
  111.         {  
  112.             printf("-->%d/%d ",p->adjvex,p->info);  
  113.             p=p->nextarc;  
  114.         }  
  115.         printf("\n");  
  116.     }  
  117. }  

main.cpp:(注:这里直接使用了参考解答中的测试函数)

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include "graph.h"  
  3. int OutDegree(ALGraph *G,int v)                        //返回图G中编号为v的顶点的出度  
  4. {  
  5.     ArcNode *p;  
  6.     int num=0;                                         //num记录每个顶点的出度  
  7.     p=G->adjlist[v].firstarc;  
  8.     while (p!=NULL)  
  9.     {  
  10.         num++;  
  11.         p=p->nextarc;  
  12.     }  
  13.     return num;  
  14. }  
  15. void OutDs(ALGraph *G)                                 //输出图G中每个顶点的出度  
  16. {  
  17.     int i;  
  18.     for(i=0;i<G->n;i++)  
  19.         printf("顶点 %d 的出度是 %d\n",i,OutDegree(G,i));  
  20. }  
  21. void OutMaxDs(ALGraph *G)                              //输出图G中出度最大的一个顶点  
  22. {  
  23.     int i;  
  24.     int maxnode;                                       //记录出度最大的顶点  
  25.     int maxdegree=0;                                   //出度最大值赋0  
  26.     for(i=0;i<G->n;i++)  
  27.     {  
  28.         if(OutDegree(G,i)>maxdegree)  
  29.         {  
  30.             maxnode=i;  
  31.             maxdegree=OutDegree(G,i);  
  32.         }  
  33.     }  
  34.     printf("出度最大的顶点为:%d,其出度为%d\n",maxnode,maxdegree);  
  35. }  
  36. void ZeroDs(ALGraph *G)                                //计算图G中出度为0的顶点数  
  37. {  
  38.     int i,zeronode=0;  
  39.     for(i=0;i<G->n;i++)  
  40.     {  
  41.         if(OutDegree(G,i)==0)  
  42.             zeronode++;  
  43.     }  
  44.     printf("图G中出度为0的顶点数为:%d\n",zeronode);  
  45. }  
  46. bool Arc(ALGraph *G,int i,int j)                       //返回图G中是否存在边<i,j>  
  47. {  
  48.     bool existence=false;                              //existence记录边是否存在,开始假定不存在  
  49.     ArcNode *p;  
  50.     p=G->adjlist[i].firstarc;  
  51.     while(p!=NULL)  
  52.     {  
  53.         if(p->adjvex==j)                               //存在边,existence置为true,跳出循环  
  54.         {  
  55.             existence=true;  
  56.             break;  
  57.         }  
  58.         p=p->nextarc;  
  59.     }  
  60.     return existence;  
  61. }  
  62. int main()                                             //测试主函数  
  63. {  
  64.     ALGraph *G;  
  65.     int A[7][7]=  
  66.     {  
  67.         {0,1,1,1,0,0,0},  
  68.         {0,0,0,0,1,0,0},  
  69.         {0,0,0,0,1,1,0},  
  70.         {0,0,0,0,0,0,1},  
  71.         {0,0,0,0,0,0,0},  
  72.         {0,0,0,1,1,0,1},  
  73.         {0,1,0,0,0,0,0}  
  74.     };  
  75.     ArrayToList(A[0], 7, G);  
  76.     printf("(1)各顶点出度:\n");  
  77.     OutDs(G);  
  78.     printf("(2)最大出度的顶点信息:");  
  79.     OutMaxDs(G);  
  80.     printf("(3)出度为0的顶点:");  
  81.     ZeroDs(G);  
  82.     printf("(4)边<2,6>存在吗?");  
  83.     if(Arc(G,2,6))  
  84.         printf("是\n");  
  85.     else  
  86.         printf("否\n");  
  87.     printf("\n");  
  88.     return 0;  
  89. }  

运行结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值