第十二周项目1-图基本算法库

来源:互联网 发布:php编程招聘 编辑:程序博客网 时间:2024/06/05 06:12

问题及代码:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  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. *问题描述:定义图的邻接矩阵和邻接表存储结构,实现其基本运算,并完成测试。  
  16. 要求:  
  17. 1、头文件graph.h中定义相关的数据结构并声明用于完成基本运算的函数。对应基本运算的函数包括: 
  18.     void ArrayToMat(int *Arr, int n, MGraph &g); //用普通数组构造图的邻接矩阵 
  19.     void ArrayToList(int *Arr, int n, ALGraph *&); //用普通数组构造图的邻接表 
  20.     void MatToList(MGraph g,ALGraph *&G);//将邻接矩阵g转换成邻接表G 
  21.     void ListToMat(ALGraph *G,MGraph &g);//将邻接表G转换成邻接矩阵g 
  22.     void DispMat(MGraph g);//输出邻接矩阵g 
  23.     void DispAdj(ALGraph *G);//输出邻接表G 
  24. 2、在graph.cpp中实现这些函数  
  25. 3、用main.cpp中的main函数中完成测试。 
  26.  
  27. *输入描述:无 
  28.  
  29. *程序输出:测试结果 
  30.  
  31. */  

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 <malloc.h>  
  3. #include "graph.h"  
  4. int main()  
  5. {  
  6.     MGraph g1,g2;  
  7.     ALGraph *G1,*G2;  
  8.     int A[6][6]=  
  9.     {  
  10.         {0,5,0,7,0,0},  
  11.         {0,0,4,0,0,0},  
  12.         {8,0,0,0,0,9},  
  13.         {0,0,5,0,0,6},  
  14.         {0,0,0,5,0,0},  
  15.         {3,0,0,0,1,0}  
  16.     };  
  17.   
  18.     ArrayToMat(A[0],6,g1);                      //取二维数组的起始地址作实参,用A[0],因其实质为一维数组地址,与形参匹配  
  19.     printf(" 有向图g1的邻接矩阵:\n");  
  20.     DispMat(g1);  
  21.   
  22.     ArrayToList(A[0],6,G1);  
  23.     printf(" 有向图G1的邻接表:\n");  
  24.     DispAdj(G1);  
  25.   
  26.     MatToList(g1,G2);  
  27.     printf(" 图g1的邻接矩阵转换成邻接表G2:\n");  
  28.     DispAdj(G2);  
  29.   
  30.     ListToMat(G1,g2);  
  31.     printf(" 图G1的邻接表转换成邻接邻阵g2:\n");  
  32.     DispMat(g2);  
  33.     printf("\n");  
  34.     return 0;  
  35. }  

运行结果:

0 0