一、实验目的
熟悉图的存储结构,掌握用单链表存储数据元素信息和数据元素之间的关系的信息的方法,并能运用图的深度优先搜索遍历一个图,对其输出。
二、实验原理
深度优先搜索遍历是树的先根遍历的推广。假设初始状态时图中所有顶点未曾访问,则深度优先搜索可从图中某个顶点v出发,访问此顶点,然后依次从v的未被访问的邻接点出发深度优先遍历图,直至图中所有与v有路径相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中一个未曾访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。
1. //算法6.3 深度优先搜索遍历连通图的递归算法 2. 3. #include <iostream> 4. using namespace std; 5. 6. #define MVNum 100 //最大顶点数 7. typedef char VerTexType; //假设顶点的数据类型为字符型 8. typedef int ArcType; //假设边的权值类型为整型 9. 10. typedef struct{ 11. VerTexType vexs[MVNum]; //顶点表 12. ArcType arcs[MVNum][MVNum]; //邻接矩阵 13. int vexnum,arcnum; //图的当前点数和边数 14. }Graph; 15. 16. bool visited[MVNum]; //访问标志数组,其初值为"false" 17. int FirstAdjVex(Graph G , int v); //返回v的第一个邻接点 18. int NextAdjVex(Graph G , int v , int w); //返回v相对于w的下一个邻接点 19. 20. int LocateVex(Graph G , VerTexType v){ 21. //确定点v在G中的位置 22. for(int i = 0; i < G.vexnum; ++i) 23. if(G.vexs[i] == v) 24. return i; 25. return -1; 26. }//LocateVex 27. 28. void CreateUDN(Graph &G){ 29. //采用邻接矩阵表示法,创建无向网G 30. int i , j , k; 31. cout <<"请输入总顶点数,总边数 , 以空格隔开:"; 32. cin >> G.vexnum >> G.arcnum; //输入总顶点数,总边数 33. cout << endl; 34. 35. cout << "输入点的名称,如 a:" << endl; 36. 37. for(i = 0; i < G.vexnum; ++i){ 38. cout << "请输入第" << (i+1) << "个点的名称:"; 39. cin >> G.vexs[i]; //依次输入点的信息 40. } 41. cout << endl; 42. 43. for(i = 0; i < G.vexnum; ++i) //初始化邻接矩阵,边的权值均置为极大值MaxInt 44. for(j = 0; j < G.vexnum; ++j) 45. G.arcs[i][j] = 0; 46. cout << "输入边依附的顶点,如:a b" << endl; 47. for(k = 0; k < G.arcnum;++k){ //构造邻接矩阵 48. VerTexType v1 , v2; 49. cout << "请输入第" << (k + 1) << "条边依附的顶点:"; 50. cin >> v1 >> v2; //输入一条边依附的顶点及权值 51. i = LocateVex(G, v1); j = LocateVex(G, v2); //确定v1和v2在G中的位置,即顶点数组的下标 52. G.arcs[j][i] = G.arcs[i][j] = 1; //置<v1, v2>的对称边<v2, v1>的权值为w 53. }//for 54. }//CreateUDN 55. 56. void DFS(Graph G, int v){ //从第v个顶点出发递归地深度优先遍历图G 57. cout << G.vexs[v] << " "; visited[v] = true; //访问第v个顶点,并置访问标志数组相应分量值为true 58. int w; 59. for(w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G, v, w)) 60. //依次检查v的所有邻接点w ,FirstAdjVex(G, v)表示v的第一个邻接点 61. //NextAdjVex(G, v, w)表示v相对于w的下一个邻接点,w≥0表示存在邻接点 62. if(!visited[w]) DFS(G, w); //补充代码 63. //对v的尚未访问的邻接顶点w递归调用DFS 64. }//DFS 65. 66. int FirstAdjVex(Graph G , int v){ 67. int i; 68. for(i = 0 ; i < G.vexnum ; ++i){ 69. if(G.arcs[v][i] == 1 && visited[i] == false) 70. return i; 71. } 72. return -1; 73. }//FirstAdjVex 74. 75. int NextAdjVex(Graph G , int v , int w){ 76. int i; 77. for(i = w ; i < G.vexnum ; ++i){ 78. if(G.arcs[v][i] == 1 && visited[i] == false) 79. return i; 80. } 81. return -1; 82. }//NextAdjVex 83. 84. int main(){ 85. cout << "************算法6.3 深度优先搜索遍历连通图的递归算法**************" << endl << endl; 86. Graph G; 87. CreateUDN(G); 88. cout << endl; 89. cout << "无向连通图G创建完成!" << endl << endl; 90. 91. cout << "请输入遍历连通图的起始点:"; 92. VerTexType c; 93. cin >> c; 94. 95. int i; 96. for(i = 0 ; i < G.vexnum ; ++i){ 97. if(c == G.vexs[i]) 98. break; 99. } 100. cout << endl; 101. while(i >= G.vexnum){ 102. cout << "该点不存在,请重新输入!" << endl; 103. cout << "请输入遍历连通图的起始点:"; 104. cin >> c; 105. for(i = 0 ; i < G.vexnum ; ++i){ 106. if(c == G.vexs[i]) 107. break; 108. } 109. } 110. cout << "深度优先搜索遍历连通图结果:" << endl; 111. DFS(G , i); 112. 113. cout <<endl; 114. return 0; 115. }//main