第十二周项目3-图遍历算法实现(1-深度优先遍历)

来源:互联网 发布:注册公司怎么域名 编辑:程序博客网 时间:2024/05/29 15:18
  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. *问题描述:实现图遍历算法,输出如下图结构的深度优先(DFS)遍历序列。 
  16.  
  17. *输入描述:无 
  18.  
  19. *程序输出:测试结果 
  20.  
  21. */  

graph.h:

[cpp] view plain copy
  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
  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 visited[MAXV];                                   //定义visited[] 全局数组,记录顶点访问情况  
  4. void DFS(ALGraph *G,int v)                           //深度优先遍历,v是初始顶点编号  
  5. {  
  6.     ArcNode *p;  
  7.     visited[v]=1;                                    //置该顶点为已访问  
  8.     printf("%d ",v);                                 //输出已访问顶点编号  
  9.     p=G->adjlist[v].firstarc;                        //p指向顶点v的第一个邻接点  
  10.     while(p!=NULL)  
  11.     {  
  12.         if(visited[p->adjvex]==0)                    //p->adjvex顶点未访问时,递归访问该顶点  
  13.             DFS(G,p->adjvex);  
  14.         p=p->nextarc;  
  15.     }  
  16. }  
  17. int main()  
  18. {  
  19.     int i;  
  20.     ALGraph *G;  
  21.     int A[6][6]=  
  22.     {  
  23.         {0,1,1,1,0,0},  
  24.         {1,0,1,0,1,0},  
  25.         {1,1,0,0,0,1},  
  26.         {1,0,0,0,0,1},  
  27.         {0,1,0,0,0,1},  
  28.         {0,0,1,1,1,0}  
  29.     };  
  30.     ArrayToList(A[0],6,G);  
  31.   
  32.     for(i=0; i<MAXV; i++)  
  33.         visited[i]=0;  
  34.     printf(" 由2开始深度遍历:");  
  35.     DFS(G,2);  
  36.     printf("\n");  
  37.   
  38.     for(i=0; i<MAXV; i++)  
  39.         visited[i]=0;  
  40.     printf(" 由0开始深度遍历:");  
  41.     DFS(G,0);  
  42.     printf("\n");  
  43.     return 0;  
  44. }  

运行结果:

0 0