当前位置:   article > 正文

图的基本操作及BFS与DFS的实现以及飞机换乘问题_dfs算法换乘问题

dfs算法换乘问题

运用STL中的queue队列实现BFS。

  1. #include<iostream>
  2. #include<queue>
  3. #include<cstdio>
  4. using namespace std;
  5. enum ResultCode { Underflow, Duplicate, Failure, Success, NotPresent };
  6. template<class T>
  7. class Graph
  8. {
  9. public:
  10. virtual ResultCode Insert(int u, int v, T&w) = 0;
  11. virtual ResultCode Remove(int u, int v) = 0;
  12. virtual bool Exist(int u, int v)const = 0;
  13. protected:
  14. int n, e;
  15. };
  16. template<class T>
  17. class MGraph :public Graph<T> //邻接矩阵类
  18. {
  19. public:
  20. MGraph(int mSize, const T& noedg);
  21. ~MGraph();
  22. ResultCode Insert(int u, int v, T&w);
  23. ResultCode Remove(int u, int v);
  24. bool Exist(int u, int v)const;
  25. void DFS();
  26. void BFS();
  27. protected:
  28. T **a;
  29. T noEdge;
  30. void DFS(int v, bool *visited);
  31. void BFS(int v, bool *visited);
  32. };
  33. template<class T>
  34. void MGraph<T>::DFS() //深度优先遍历
  35. {
  36. bool *visited = new bool[n];
  37. for (int i = 0; i<n; i++)
  38. visited[i] = false;
  39. for (int i = 0; i<n; i++)
  40. if (!visited[i])
  41. DFS(i, visited);
  42. delete[]visited;
  43. cout << endl;
  44. }
  45. template<class T>
  46. void MGraph<T>::DFS(int v, bool *visited)
  47. {
  48. visited[v] = true;
  49. cout << " " << v;
  50. for (int i = 0; i < n; i++)
  51. if (a[v][i] != noEdge&&a[v][i] != 0 && !visited[i])
  52. DFS(i, visited);
  53. }
  54. template<class T>
  55. void MGraph<T>::BFS() //宽度游先遍历
  56. {
  57. bool *visited = new bool[n];
  58. for (int i = 0; i<n; i++)
  59. visited[i] = false;
  60. for (int i = 0; i<n; i++)
  61. if (!visited[i])
  62. BFS(i, visited);
  63. delete[]visited;
  64. cout << endl;
  65. }
  66. template<class T>
  67. void MGraph<T>::BFS(int v, bool *visited)
  68. {
  69. visited[v] = true;
  70. cout << " " << v;
  71. queue<int> q;
  72. q.push(v);
  73. while (!q.empty())
  74. {
  75. v=q.front();
  76. q.pop();
  77. for (int i = 0; i < n; i++)
  78. {
  79. if (a[v][i] != noEdge&&a[v][i] != 0 && !visited[i])
  80. {
  81. visited[i] = true;
  82. cout << " " << i;
  83. q.push(i);
  84. }
  85. }
  86. }
  87. }
  88. template <class T>
  89. MGraph<T>::MGraph(int mSize, const T&noedg) //构造函数
  90. {
  91. n = mSize;
  92. e = 0;
  93. noEdge = noedg;
  94. a = new T*[n];
  95. for (int i = 0; i<n; i++)
  96. {
  97. a[i] = new T[n];
  98. for (int j = 0; j<n; j++)
  99. a[i][j] = noEdge;
  100. a[i][i] = 0;
  101. }
  102. }
  103. template <class T>
  104. MGraph<T>::~MGraph() //析构函数
  105. {
  106. for (int i = 0; i<n; i++)
  107. delete[]a[i];
  108. delete[]a;
  109. }
  110. template <class T>
  111. ResultCode MGraph<T>::Insert(int u, int v, T&w) //插入函数
  112. {
  113. if (u<0 || v<0 || u>n - 1 || v>n - 1 || u == v)
  114. return Failure;
  115. if (a[u][v] != noEdge)
  116. return Duplicate;
  117. a[u][v] = w;
  118. e++;
  119. return Success;
  120. }
  121. template <class T>
  122. ResultCode MGraph<T>::Remove(int u, int v) //删除函数
  123. {
  124. if (u<0 || v<0 || u>n - 1 || v>n - 1 || u == v)
  125. return Failure;
  126. if (a[u][v] == noEdge)
  127. return NotPresent;
  128. a[u][v] = noEdge;
  129. e--;
  130. return Success;
  131. }
  132. template<class T>
  133. bool MGraph<T>::Exist(int u, int v)const //判断边是否存在
  134. {
  135. if (u<0 || v<0 || u>n - 1 || v>n - 1 || u == v || a[u][v] == noEdge)
  136. return false;
  137. return true;
  138. }
  139. template<class T> //结点类
  140. class ENode
  141. {
  142. public:
  143. ENode() { nextArc = NULL; }
  144. ENode(int vertex, T weight, ENode *next)
  145. {
  146. adjVex = vertex;
  147. w = weight;
  148. nextArc = next;
  149. }
  150. int adjVex;
  151. T w;
  152. ENode * nextArc;
  153. };
  154. template <class T>
  155. class LGraph :public Graph<T> //邻接表类
  156. {
  157. public:
  158. LGraph(int mSize);
  159. ~LGraph();
  160. ResultCode Insert(int u, int v, T&w);
  161. ResultCode Remove(int u, int v);
  162. bool Exist(int u, int v)const;
  163. protected:
  164. ENode<T> **a;
  165. };
  166. template <class T>
  167. LGraph<T>::LGraph(int mSize) //构造函数
  168. {
  169. n = mSize;
  170. e = 0;
  171. a = new ENode<T> *[n];
  172. for (int i = 0; i<n; i++)
  173. a[i] = NULL;
  174. }
  175. template <class T>
  176. LGraph<T>::~LGraph() //析构函数
  177. {
  178. ENode<T> *p, *q;
  179. for (int i = 0; i<n; i++)
  180. {
  181. p = a[i];
  182. q = p;
  183. while (p)
  184. {
  185. p = p->nextArc;
  186. delete q;
  187. q = p;
  188. }
  189. }
  190. delete[]a;
  191. }
  192. template <class T>
  193. bool LGraph<T>::Exist(int u, int v)const //判断边是否存在
  194. {
  195. if (u<0 || v<0 || u>n - 1 || v>n - 1 || u == v)
  196. return false;
  197. ENode<T>*p = a[u];
  198. while (p&&p->adjVex != v)
  199. p = p->nextArc;
  200. if (!p)
  201. return false;
  202. else return true;
  203. }
  204. template <class T>
  205. ResultCode LGraph<T>::Insert(int u, int v, T&w) //插入函数
  206. {
  207. if (u<0 || v<0 || u>n - 1 || v>n - 1 || u == v)
  208. return Failure;
  209. if (Exist(u, v))
  210. return Duplicate;
  211. ENode<T>*p = new ENode<T>(v, w, a[u]);
  212. a[u] = p;
  213. e++;
  214. return Success;
  215. }
  216. template <class T>
  217. ResultCode LGraph<T>::Remove(int u, int v) //删除函数
  218. {
  219. if (u<0 || v<0 || u>n - 1 || v>n - 1 || u == v)
  220. return Failure;
  221. ENode<T> *p = a[u], *q;
  222. q = NULL;
  223. while (p&&p->adjVex != v)
  224. {
  225. q = p;
  226. p = p->nextArc;
  227. }
  228. if (!p)
  229. return NotPresent;
  230. if (q)
  231. q->nextArc = p->nextArc;
  232. else
  233. a[u] = p->nextArc;
  234. delete p;
  235. e--;
  236. return Success;
  237. }
  238. int main() //主函数,测试上述运算
  239. {
  240. int m, n; //m代表元素个数,n代表边的条数
  241. cout << "请按顺序依次输入元素的个数和边数" << endl;
  242. cin >> m >> n;
  243. MGraph<int> A(m, -1);
  244. LGraph<int> B(m);
  245. int a, b, c;
  246. for (int i = 0; i<n; i++)
  247. {
  248. cout << "按顺序输入边和权值(例如 1 2 3)" << endl;
  249. cin >> a >> b >> c;
  250. A.Insert(a, b, c);
  251. B.Insert(a, b, c);
  252. }
  253. cout << "深度优先遍历如下:" << endl;
  254. A.DFS();
  255. cout << "宽度优先遍历如下:" << endl;
  256. A.BFS();
  257. cout << endl;
  258. char mm;
  259. cout << "输入要进行的选项" << endl << "1.查找边" << endl << "2.删除边" << endl << "3.遍历" << endl << "0.退出" << endl;
  260. while (cin >> mm)
  261. {
  262. getchar();
  263. switch (mm)
  264. {
  265. case '1':
  266. cout << "请输入要搜索的边: ";
  267. int c, d;
  268. cin >> c >> d;
  269. if (A.Exist(c, d))
  270. cout << "邻接矩阵中该边存在!" << endl;
  271. else
  272. cout << "邻接矩阵中该边不存在!" << endl;
  273. if (B.Exist(c, d))
  274. cout << "邻接表中该边存在!" << endl;
  275. else
  276. cout << "邻接表中该边不存在!" << endl;
  277. break;
  278. case '2':
  279. cout << "请输入要删除的边: ";
  280. int e, f;
  281. cin >> e >> f;
  282. if (A.Remove(e, f) == Success)
  283. cout << "邻接矩阵中删除该边成功!" << endl;
  284. else if (A.Remove(e, f) == NotPresent)
  285. cout << "邻接矩阵中该边不存在!" << endl;
  286. else
  287. cout << "输入错误!" << endl;
  288. if (B.Remove(e, f) == Success)
  289. cout << "邻接表中删除该边成功!" << endl;
  290. else if (B.Remove(e, f) == NotPresent)
  291. cout << "邻接表中该边不存在!" << endl;
  292. else
  293. cout << "邻接表中输入错误!" << endl;
  294. break;
  295. case '3':
  296. cout << "深度优先遍历如下:" << endl;
  297. A.DFS();
  298. cout << "宽度优先遍历如下:" << endl;
  299. A.BFS();
  300. break;
  301. case '0':
  302. exit(0);
  303. default:
  304. continue;
  305. }
  306. }
  307. return 0;
  308. }

飞机问题主要运用弗罗伊德算法然后改变了主函数部分代码如下:

  1. template<class T>
  2. void MGraph<T>::Floyd(T **d, int **path) //弗罗伊德算法
  3. {
  4. int i, k, j;
  5. for (i = 0; i < n; i++)
  6. for (j = 0; j < n; j++)
  7. {
  8. d[i][j] = a[i][j];
  9. if (i != j&&a[i][j]<INFTY)
  10. path[i][j] = i;
  11. else
  12. path[i][j] = -1;
  13. }
  14. for (k = 0; k < n; k++)
  15. for (i = 0; i < n; i++)
  16. for (j = 0; j < n;j++)
  17. if (d[i][k] + d[k][j] < d[i][j])
  18. {
  19. d[i][j] = d[i][k] + d[k][j];
  20. path[i][j] = path[k][j];
  21. }
  22. }


相应的主函数

  1. int main()
  2. {
  3. int n, m;//n个城市,m条航线
  4. const int weight=1;
  5. cout << "输入城市个数n以及航线条数m" << endl;
  6. cin >> n >> m;
  7. int **d = new int*[n], **path = new int*[n];
  8. for (int k = 0; k < n; k++)
  9. {
  10. d[k] = new int[n];
  11. path[k] = new int[n];
  12. }
  13. MGraph<int> A(n, INFTY);
  14. for (int i = 0; i < m; i++)
  15. {
  16. int ss, qq;
  17. cout << "输入航线即两个城市" << endl;
  18. cin >> ss >> qq;
  19. A.Insert(ss, qq, weight);
  20. }
  21. A.Floyd(d, path);
  22. int x, y;
  23. cout << "请输入你要查询的起点城市和终点城市" << endl;
  24. cin >> x >> y;
  25. cout << "换乘次数最少的路线为:" << endl;
  26. int ans[1000],k=0;
  27. ans[k] = y;
  28. do
  29. {
  30. int temp = path[x][ans[k]];
  31. ans[++k] = temp;
  32. } while (path[x][ans[k-1]] != x);
  33. do
  34. cout << " " << ans[k] << endl;
  35. while (k--);
  36. for (int k = 0; k < n; k++)
  37. {
  38. delete[]d[k];
  39. delete[]path[k];
  40. }
  41. delete[]d;
  42. delete[]path;
  43. return 0;
  44. }


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/582897
推荐阅读
相关标签
  

闽ICP备14008679号