C++实现邻接表无向图及其两种遍历

x33g5p2x  于2021-09-24 转载在 C/C++  
字(2.4k)|赞(0)|评价(0)|浏览(741)
  1. #include<iostream>
  2. #include<string.h>
  3. #include<queue>
  4. #define MaxSize 100 //最大结点数
  5. using namespace std;
  6. typedef struct ArcNode //存储与结点相连的边
  7. {
  8. int adjvex; //该边所指向的顶点的位置
  9. ArcNode* nextarc; //指向下一条与结点相连的边
  10. int weight; //边的权重
  11. }ArcNode;
  12. typedef struct VNode //存储结点信息
  13. {
  14. char data; //结点数据域
  15. ArcNode *firstArc; //结点指针域,指向与其相连的第一个边
  16. }VNode;
  17. class UndiGraph //无向图
  18. {
  19. public:
  20. UndiGraph();
  21. int LocateVex(char a); //寻找数据域为a的结点的位置
  22. void CreatGraph(); //创建无向图
  23. void Visit(int i); //访问i位置上的结点数据
  24. void dfs(int a=0); //连通图的深度优先遍历
  25. void DFS(int a=0); //图的深度优先遍历,这里的图可以是连通图,也可以是非连通图
  26. void bfs(int a=0); //连通图广度优先遍历
  27. void BFS(int a=0); //图的广度优先遍历,这里的图可以是连通图,也可以是非连通图
  28. private:
  29. int vexnum; //结点数
  30. int arcnum; //边数
  31. VNode list[MaxSize]; //结点表,存储所有的结点
  32. bool visited[MaxSize];
  33. };
  34. UndiGraph::UndiGraph()
  35. {
  36. vexnum = arcnum = 0;
  37. memset(visited,false,sizeof(visited));
  38. }
  39. int UndiGraph::LocateVex(char a) //寻找数据域为a的结点的位置
  40. {
  41. for(int i=0; i<vexnum; ++i)
  42. {
  43. if(list[i].data==a)
  44. {
  45. return i;
  46. }
  47. }
  48. }
  49. void UndiGraph::CreatGraph() //创建无向图
  50. {
  51. cout << "输入结点个数和边数:";
  52. cin >> vexnum >> arcnum;
  53. for(int i=0; i<vexnum; ++i)
  54. {
  55. cout << "输入第" << i+1 << "个结点的值:";
  56. cin >> list[i].data;
  57. list[i].firstArc = NULL;
  58. }
  59. char a, b; //a,b记录边的两个端点的值
  60. int weight; //weight记录边的权值
  61. int p, q; //p,q记录两个端点在结点表中的位置
  62. for(int i=0; i<arcnum; ++i)
  63. {
  64. cout << "输入第" << i+1 << "条边的两个端点的值及权重:";
  65. cin >> a >> b >> weight;
  66. p = LocateVex(a);
  67. q = LocateVex(b);
  68. ArcNode *an = new ArcNode();
  69. an->adjvex =q;
  70. an->weight = weight;
  71. an->nextarc = list[p].firstArc;
  72. list[p].firstArc = an;
  73. ArcNode *bn = new ArcNode();
  74. bn->adjvex =p;
  75. bn->weight = weight;
  76. bn->nextarc = list[q].firstArc;
  77. list[q].firstArc = bn;
  78. }
  79. }
  80. void UndiGraph::Visit(int i) //访问i位置上的结点数据
  81. {
  82. cout << list[i].data;
  83. visited[i] = true;
  84. }
  85. void UndiGraph::dfs(int a) //连通图的深度优先遍历
  86. {
  87. Visit(a);
  88. VNode vn = list[a];
  89. ArcNode *an = vn.firstArc;
  90. while(an!=NULL&&!visited[an->adjvex])
  91. {
  92. dfs(an->adjvex);
  93. an = an->nextarc;
  94. }
  95. }
  96. void UndiGraph::DFS(int a) //图的深度优先遍历,这里的图可以是连通图,也可以是非连通图
  97. {
  98. for(int i=a; i<vexnum; ++i) //对每个连通分量进行深度优先遍历
  99. {
  100. if(!visited[i])
  101. {
  102. dfs(i);
  103. }
  104. }
  105. }
  106. void UndiGraph::bfs(int a) //连通图广度优先遍历
  107. {
  108. queue<int> q;
  109. q.push(a);
  110. visited[a] = true;
  111. while(!q.empty())
  112. {
  113. Visit(q.front());
  114. VNode vn = list[q.front()];
  115. ArcNode *an = vn.firstArc;
  116. while(an!=NULL) //将当前节点未被访问的兄弟结点入队列
  117. {
  118. if(!visited[an->adjvex])
  119. {
  120. q.push(an->adjvex);
  121. visited[an->adjvex] = true;
  122. }
  123. an = an->nextarc;
  124. }
  125. q.pop();
  126. }
  127. }
  128. void UndiGraph::BFS(int a) //图的广度优先遍历,这里的图可以是连通图,也可以是非连通图
  129. {
  130. for(int i=a; i<vexnum; ++i) //对每个连通分量做广度优先遍历
  131. {
  132. if(!visited[i])
  133. {
  134. bfs(i);
  135. }
  136. }
  137. }
  138. int main()
  139. {
  140. UndiGraph a;
  141. a.CreatGraph();
  142. a.DFS();
  143. }

相关文章

最新文章

更多