有向图的邻接表存储,递归和非递归的深度、广度遍历(codeblocks+gcc)



有向图的邻接表存储,递归和非递归的深度、广度遍历(codeblocks+gcc。

程序功能:

1. 图的邻接表存储

2. 递归深度遍历

3. 非递归深度遍历(借助stack)

4. 递归广度遍历

5. 非递归广度遍历(借助queue)

 

程序中通过条件编译实现,递归与非递归的选择

  1. //#define _RECURSION_TRAVERSE                                              //递归遍历(将下一行注释,此行不注释)
  2. #define _NON_RECURSION_TRAVERSE                                       //非递归遍历(节点本身有isVisited域)(将上一行注释,此行不注释)

 

注释第一行,保留第二行:实现非递归遍历

注释第二行,保留第一行:实现递归遍历

两行都注释或都不注释:出错(无此函数/函数重名)

 

程序所用图的结构

程序源代码

  1. /*****************************************************************
  2. *功  能:利用邻接表存储图,实现其递归与非递归的深度遍历和广度遍历
  3. *作  者:JarvisChu
  4. *时  间:2011-04-30
  5. *****************************************************************/
  6. #include <iostream>
  7. #include <string>
  8. #include <stack>
  9. #include <queue>
  10. using namespace std;
  11. //#define _RECURSION_TRAVERSE                                              //递归遍历(将下一行注释,此行不注释)
  12. #define _NON_RECURSION_TRAVERSE                                       //非递归遍历(节点本身有isVisited域)(将上一行注释,此行不注释)
  13. #define MAX_VERTEX_NUM 20                                                   //最大顶点数
  14. /*弧节点的结构,即每个顶点后面的单链表中的节点结构*/
  15. typedef struct ArcNode{
  16.     int adjvex;                                                                                //该弧所指向的顶点的位置
  17.     struct ArcNode* nextArc;                                                        //下一条弧
  18.     string info;                                                                               //该弧所携带的信息
  19. }ArcNode;
  20. #ifdef  _NON_RECURSION_TRAVERSE
  21. /*每个顶点的节点结构,非递归时使用*/
  22. typedef struct VNode{
  23.     bool isVisited;
  24.     string data;                                                                               //顶点的数据
  25.     ArcNode* fristArc;                                                                    //指向该顶点所接的单链表的第一个弧节点
  26. }VNode,AdjList[MAX_VERTEX_NUM];
  27. #endif
  28. #ifdef  _RECURSION_TRAVERSE
  29. /*每个顶点的节点结构,递归时使用*/
  30. typedef struct VNode{
  31.     string data;                                                                               //顶点的数据
  32.     ArcNode* fristArc;                                                                    //指向该顶点所接的单链表的第一个弧节点
  33. }VNode,AdjList[MAX_VERTEX_NUM];
  34. #endif
  35. /*图的结构*/
  36. typedef struct{
  37.     AdjList vertices;                                                                        //顶点数组
  38.     int vexNum;                                                                             //顶点数
  39.     int arcNum;                                                                              //弧数
  40.     int kind;                                                                                    //种类
  41. }Graph;
  42. /*初始化有向图*/
  43. bool InitDiGraph(Graph* pGraph){
  44.     pGraph->kind = 0;                                                                   //有向图
  45.     pGraph->vexNum = 5;
  46.     pGraph->arcNum = 5;
  47.     pGraph->vertices[0].data = “V0″;                                             //顶点V0的邻接表
  48. #ifdef _NON_RECURSION_TRAVERSE
  49.     pGraph->vertices[0].isVisited = false;
  50. #endif
  51.     ArcNode* node = new ArcNode();
  52.     node->adjvex = 1;
  53.     node->info = “V0–>V1″;
  54.     node->nextArc = NULL;
  55.     ArcNode* node1 = new ArcNode();
  56.     node1->adjvex = 2;
  57.     node1->info = “V0–>V2″;
  58.     node1->nextArc = NULL;
  59.     node->nextArc = node1;
  60.     pGraph->vertices[0].fristArc = node;
  61.     pGraph->vertices[1].data = “V1″;                                             //顶点V1的邻接表
  62. #ifdef _NON_RECURSION_TRAVERSE
  63.     pGraph->vertices[1].isVisited = false;
  64. #endif
  65.     pGraph->vertices[1].fristArc = NULL;
  66.     pGraph->vertices[2].data = “V2″;                                             //顶点V2的邻接表
  67. #ifdef _NON_RECURSION_TRAVERSE
  68.     pGraph->vertices[2].isVisited = false;
  69. #endif
  70.     node = new ArcNode();
  71.     node->adjvex = 3;
  72.     node->info = “V2–>V3″;
  73.     node->nextArc = NULL;
  74.     pGraph->vertices[2].fristArc = node;
  75.     pGraph->vertices[3].data = “V3″;                                             //顶点V3的邻接表
  76. #ifdef _NON_RECURSION_TRAVERSE
  77.     pGraph->vertices[3].isVisited = false;
  78. #endif
  79.     node = new ArcNode();
  80.     node->adjvex = 0;
  81.     node->info = “V3–>V0″;
  82.     node->nextArc = NULL;
  83.     node1 = new ArcNode();
  84.     node1->adjvex = 4;
  85.     node1->info = “V3–>V4″;
  86.     node1->nextArc = NULL;
  87.     node->nextArc = node1;
  88.     pGraph->vertices[3].fristArc = node;
  89.     pGraph->vertices[4].data = “V4″;                                             //顶点V4的邻接表
  90. #ifdef _NON_RECURSION_TRAVERSE
  91.     pGraph->vertices[4].isVisited = false;
  92. #endif
  93.     pGraph->vertices[4].fristArc = NULL;
  94.     return true;
  95. }
  96. /*显示有向图*/
  97. bool DisplayDiGraph(Graph diGraph){
  98.     cout<<”*******************图信息********************”<<endl;
  99.     cout<<”图种类为:”<<diGraph.kind<<endl;
  100.     cout<<”顶点数为:”<<diGraph.vexNum<<endl;
  101.     cout<<”弧数为:”<<diGraph.arcNum<<endl<<endl;
  102.     cout<<”邻接表结构如下”<<endl;
  103.     ArcNode* node = NULL;
  104.     for(int i=0;i<diGraph.vexNum;i++){
  105.         cout<<diGraph.vertices[i].data<<”:”;
  106.         node = diGraph.vertices[i].fristArc;
  107.         while(node != NULL){
  108.             cout<<”(“<<node->adjvex<<”,”<<node->info<<”) ; “;
  109.             node = node->nextArc;
  110.         }
  111.         cout<<endl;
  112.     }
  113.     return true;
  114. }
  115. #ifdef _NON_RECURSION_TRAVERSE
  116. /*深度优先非递归遍历有向图,利用栈*/
  117. bool Depth_First_Traverse(Graph* pDiGraph){
  118.     for(int i=0;i<pDiGraph->vexNum;i++){                  //初始化,全为false
  119.         pDiGraph->vertices[i].isVisited = false;
  120.     }
  121.     VNode* vnode;
  122.     stack<VNode*> TraverseStack;                                                 //用stack实现非递归遍历算法
  123.     TraverseStack.push(&(pDiGraph->vertices[0]));                                   //第一个节点入栈
  124.     while(!TraverseStack.empty()){
  125.         vnode = (VNode*)TraverseStack.top();                                                //获得栈顶节点
  126.         vnode->isVisited = true;
  127.         cout<<”遍历:”<<vnode->data<<endl;
  128.         TraverseStack.pop();
  129.         ArcNode* node = vnode->fristArc;
  130.         while(node != NULL){
  131.             if(!(pDiGraph->vertices[node->adjvex]).isVisited){
  132.                 TraverseStack.push(&(pDiGraph->vertices[node->adjvex]));        //入栈
  133.             }
  134.             node = node->nextArc;
  135.         }
  136.     }
  137.     return true;
  138. }
  139. #endif
  140. #ifdef _RECURSION_TRAVERSE
  141. /*深度优先递归遍历时,用来遍历每一个顶点*/
  142. bool DFT(Graph* pDiGraph,bool* visited,int i){
  143.     if(!visited[i]){
  144.         visited[i] = true;                                                 //标志该顶点已被访问了
  145.         cout<<”遍历:”<<pDiGraph->vertices[i].data<<endl;
  146.         ArcNode* node = pDiGraph->vertices[i].fristArc;//遍历其临街单链表
  147.         while(node != NULL){
  148.             DFT(pDiGraph,visited,node->adjvex);
  149.             node = node->nextArc;
  150.         }
  151.     }
  152.     return true;
  153. }
  154. /*深度优先递归遍历有向图*/
  155. bool Depth_First_Traverse(Graph* pDiGraph){
  156.     int size = pDiGraph->vexNum;                           //顶点数目
  157.     bool* visited = new bool[size];                          //访问标志数组
  158.     for(int i = 0;i < size;i++){                                    //初始化,全为false
  159.         visited[i] = false;
  160.     }
  161.     for(int i = 0;i<size;i++){                                      //
  162.             DFT(pDiGraph,visited,i);
  163.     }
  164.     delete[] visited;
  165.     return true;
  166. }
  167. #endif
  168. #ifdef _NON_RECURSION_TRAVERSE
  169. /*广度优先非递归遍历有向图,利用队列*/
  170. bool Breadth_First_Traverse(Graph* pDiGraph){
  171.     for(int i=0;i<pDiGraph->vexNum;i++){                  //初始化,全为false
  172.         pDiGraph->vertices[i].isVisited = false;
  173.     }
  174.     VNode* vnode;
  175.     queue<VNode*> TraverseQueue;                                                 //用queue实现非递归遍历算法
  176.     TraverseQueue.push(&(pDiGraph->vertices[0]));                           //第一个节点入队
  177.     while(!TraverseQueue.empty()){
  178.         vnode = (VNode*)TraverseQueue.front();                                  //获得队首节点
  179.         vnode->isVisited = true;
  180.         cout<<”遍历:”<<vnode->data<<endl;
  181.         TraverseQueue.pop();
  182.         ArcNode* node = vnode->fristArc;
  183.         while(node != NULL){
  184.             if(!(pDiGraph->vertices[node->adjvex]).isVisited){
  185.                 TraverseQueue.push(&(pDiGraph->vertices[node->adjvex]));        //入队
  186.             }
  187.             node = node->nextArc;
  188.         }
  189.     }
  190.     return true;
  191. }
  192. #endif
  193. #ifdef _RECURSION_TRAVERSE
  194. /*广度优先递归遍历时,用来遍历每一个顶点*/
  195. bool BFT(Graph* pDiGraph,bool* visited,int i){
  196.     if(!visited[i]){
  197.         visited[i] = true;                                                 //标志该顶点已被访问了
  198.         cout<<”遍历:”<<pDiGraph->vertices[i].data<<endl;
  199.         ArcNode* node = pDiGraph->vertices[i].fristArc;//遍历其临街单链表
  200.         while(node != NULL){
  201.             if(!pDiGraph->vertices[node->adjvex].isVisited){
  202.                 pDiGraph->vertices[node->adjvex].isVisited = true;
  203.                 cout<<”遍历:”<<pDiGraph->vertices[node->adjvex].data<<endl;
  204.             }
  205.             node = node->nextArc;
  206. //       BFT(pDiGraph,visited,node->adjvex);
  207.         }
  208.         BFT(pDiGraph,visited,node->adjvex);
  209.     }
  210.     return true;
  211. }
  212. /*广度优先递归遍历有向图*/
  213. bool Breadth_First_Traverse(Graph* pDiGraph){
  214.     int size = pDiGraph->vexNum;                           //顶点数目
  215.     bool* visited = new bool[size];                          //访问标志数组
  216.     for(int i = 0;i < size;i++){                                    //初始化,全为false
  217.         visited[i] = false;
  218.     }
  219.     for(int i = 0;i<size;i++){                                      //
  220.             BFT(pDiGraph,visited,i);
  221.     }
  222.     delete[] visited;
  223. }
  224. #endif
  225. int main()
  226. {
  227.     Graph diGraph;                                                                         //有向图
  228.     Graph udiGraph;                                                                       //无向图
  229.     InitDiGraph(&diGraph);                                                             //初始化有向图,构建
  230.     DisplayDiGraph(diGraph);                                                         //显示该有向图
  231.     cout<<endl<<”***************深度优先遍历结果***********”<<endl;
  232.     Depth_First_Traverse(&diGraph);                                           //深度优先遍历
  233.     cout<<endl<<”***************广度优先遍历结果***********”<<endl;
  234.     Breadth_First_Traverse(&diGraph);                                           //广度优先遍历
  235.     return 0;
  236. }

 

 

程序运行结果

0 表示有向图