最近在学数据结构,学到图这一章,网上的C++版本的代码乱得不行,所以自己写了一个完整C++版本的放这里。

用邻接多重表表示一个无向图,并给出DFS和BFS搜索代码。邻接多重表好处就是贼直观,几条边就几个边表的元素。

代码如下:

边表节点定义(其实就是边的定义)

  1. typedef struct EdgeNode //邻接多重表
  2. {
  3. int iVertex;
  4. EdgeNode* iLink;
  5. int jVertex;
  6. EdgeNode* jLink;
  7.  
  8. };

顶点表节点的定义

  1. template <typename Type>
  2. struct VextexNode //邻接多重表的顶点表
  3. {
  4. Type Data;
  5. EdgeNode* TailLink;
  6. Mark Flag;
  7. };

最后是图的模板类

  1. #ifndef MULADJACENCYLIST_H
  2. #define MULADJACENCYLIST_H
  3. #include "SideNode.h"
  4. #include "VexNode.h"
  5. #include <iostream>
  6. #include <vector>
  7. #include <list>
  8. #include <set>
  9. using namespace std;
  10.  
  11. template <typename Type, int N>
  12. class MulAdjacencyList
  13. {
  14. public:
  15. MulAdjacencyList();
  16. ~MulAdjacencyList();
  17. void AddEdge();
  18. int DeleteEdge(int x, int y);
  19. void DFS(int x, const Type& Value);
  20. void BFS(int x, const Type& Value);
  21. private:
  22. int InitEdgeNum(); //构造函数中先输入图的边数
  23. int NextIndex(int CurIndex); //查找最近的一个邻接点,CurIndex为点的下标而不是值
  24. void BFSHelper(set <int> SourceList, const Type& Value); //BFS真正的递归函数
  25. void AllNextIndex(int i); //和i相连的所有邻接点,i为点的下标而不是值
  26. VextexNode <Type> VertexArray[N]; //顶点表
  27. EdgeNode* LastPtr(int x);
  28. int EdgeNums; //当前的边数
  29. vector <int> Temp; //用来存放搜索结果的容器
  30. set <int> TempList; //用来存放AllNextIndex结果的容器
  31. };
  32.  
  33. template <typename Type, int N>
  34. void MulAdjacencyList<Type, N>::AddEdge() //添加一条x到y的无向边
  35. {
  36. cout << "Enter the edge wanna insert!" << endl;
  37. int i, j;
  38. if (cin >> i >> j)
  39. {
  40. EdgeNode* TarPtr = new EdgeNode;
  41. TarPtr->iVertex = i;
  42. TarPtr->jVertex = j;
  43. TarPtr->iLink = VertexArray[i].TailLink;
  44. TarPtr->jLink = VertexArray[j].TailLink;
  45. VertexArray[i].TailLink = TarPtr;
  46. VertexArray[j].TailLink = TarPtr;
  47. EdgeNums++;
  48. }
  49. else
  50. cin.clear();
  51. }
  52.  
  53. template <typename Type, int N>
  54. int MulAdjacencyList<Type, N>::InitEdgeNum()
  55. {
  56. cout << "Enter the quantity of edges!"<< endl;
  57. cin >> EdgeNums;
  58. return EdgeNums;
  59. }
  60.  
  61. template <typename Type, int N>
  62. EdgeNode* MulAdjacencyList<Type, N>::LastPtr(int x) //找到和x相关的最后一条边
  63. {
  64. EdgeNode* Temp = VertexArray[x].TailLink;
  65. EdgeNode* LastTemp = Temp;
  66. while (Temp != NULL)
  67. {
  68. if (Temp->iVertex == x)
  69. {
  70. LastTemp = Temp;
  71. Temp = Temp->iLink;
  72. }
  73. else if (Temp->jVertex == x)
  74. {
  75. LastTemp = Temp;
  76. Temp = Temp->jLink;
  77. }
  78. }
  79. return LastTemp;
  80. }
  81.  
  82. template <typename Type, int N>
  83. MulAdjacencyList <Type, N>::MulAdjacencyList()
  84. {
  85. cout << "enter the vertex for the graph!" << endl;
  86. for (int i = ; i != N; ++i)
  87. {
  88. cin >> VertexArray[i].Data;
  89. VertexArray[i].TailLink = NULL;
  90. VertexArray[i].Flag = No;
  91. }
  92. int Temp = InitEdgeNum();
  93. for (int i = ; i != Temp; ++ i)
  94. AddEdge();
  95. }
  96.  
  97. template <typename Type, int N>
  98. int MulAdjacencyList<Type, N>::DeleteEdge(int x, int y) //删除x到y的一条无向边
  99. {
  100. if (x == y)return ;
  101. EdgeNode* Q = VertexArray[x].TailLink; //Q的下一条边就是要删除的边
  102. EdgeNode* P = VertexArray[x].TailLink; //先从x出发找到要删除的边,调整完x的边的次序,得到指针,最后再删除
  103. if (P && P->jVertex == y) //假如第一条边就是待删除的边, P是前向判断,避免P为NULL的情况下还执行P->jVertex
  104. VertexArray[x].TailLink = P->iLink;
  105. else if (P && P->iVertex == y)
  106. VertexArray[x].TailLink = P->jLink;
  107. else //假如第一条边不是要删除的边,则向下查找
  108. {
  109. while (P)
  110. {
  111. if (P->iVertex == x && P->jVertex != y)//不是要删除的边
  112. {
  113. Q = P;
  114. P = P->iLink;
  115. }
  116. else if (P->jVertex == x && P->iVertex != y)
  117. {
  118. Q = P;
  119. P = P->jLink;
  120. }
  121. else //找到了邻接点y
  122. break;
  123. }
  124. if (P == NULL)
  125. {
  126. return ; //这里可以加入一句警告“Not Found”
  127. }
  128. else if (P->iVertex == x && P->jVertex == y) //找到了边(x,y),调整x的边的次序
  129. {
  130. if (Q->iVertex == x)
  131. Q->iLink = P->iLink;
  132. else
  133. Q->jLink = P->iLink;
  134. }
  135. else if (P->iVertex == y && P->jVertex == x)
  136. {
  137. if (Q->iVertex == x)
  138. Q->iLink = P->jLink;
  139. else
  140. Q->jLink = P->jLink;
  141. }
  142. }
  143.  
  144. P = VertexArray[y].TailLink; //从y出发开始查找,调整y的边的次序
  145. if (P && P->iVertex == x)
  146. VertexArray[y].TailLink = P->jLink;
  147. else if (P && P->jVertex == x)
  148. VertexArray[y].TailLink = P->iLink;
  149. else
  150. {
  151. while (P != NULL)
  152. {
  153. if (P->iVertex == y && P->jVertex != x)
  154. {
  155. Q = P;
  156. P = P->iLink;
  157. }
  158. else if (P->jVertex == y && P->iVertex != x)
  159. {
  160. Q = P;
  161. P = P->jLink;
  162. }
  163. else
  164. break;
  165. }
  166. if (P == NULL) //由于上面打了一次警告,这里就不打警告了
  167. return ;
  168. else if (P->iVertex == y && P->jVertex == x)
  169. {
  170. if (Q->iVertex == y)
  171. Q->iLink = P->iLink;
  172. else
  173. Q->jLink = P->iLink;
  174. }
  175. else if ((P->jVertex == y && P->iVertex == x))
  176. {
  177. if (Q->iVertex == y)
  178. Q->iLink = P->jLink;
  179. else
  180. Q->jLink = P->jLink;
  181. }
  182. }
  183. cout << x << endl << y << endl<<"yici"<<endl;
  184. if (P != NULL) delete P; //调整完线序了,删掉边
  185. --EdgeNums;
  186. return ;
  187. }
  188.  
  189. template <typename Type, int N>
  190. MulAdjacencyList <Type, N>::~MulAdjacencyList()
  191. {
  192. for (int i = ; i != N; ++i)
  193. {
  194. for (int j = ; j != N; ++j)
  195. DeleteEdge(i,j);
  196. }
  197. }
  198.  
  199. template <typename Type, int N>
  200. void MulAdjacencyList <Type, N>::AllNextIndex(int i) //找到和i相关联的所有的点
  201. {
  202. EdgeNode* Ptr = VertexArray[i].TailLink;
  203. while (Ptr != NULL)
  204. {
  205. if (Ptr->iVertex == i)
  206. {
  207. if (VertexArray[Ptr->jVertex].Flag != Yes)TempList.insert(Ptr->jVertex);
  208. Ptr = Ptr->iLink;
  209. }
  210. else
  211. {
  212. if (VertexArray[Ptr->iVertex].Flag != Yes)TempList.insert(Ptr->iVertex);
  213. Ptr = Ptr->jLink;
  214. }
  215. }
  216. }
  217.  
  218. template <typename Type, int N>
  219. int MulAdjacencyList <Type, N>::NextIndex(int CurIndex)
  220. {
  221. EdgeNode* Ptr = VertexArray[CurIndex].TailLink;
  222. while (Ptr != NULL)
  223. {
  224. if (Ptr->iVertex == CurIndex)
  225. {
  226. if (VertexArray[Ptr->jVertex].Flag == No){
  227. return Ptr->jVertex;
  228. }
  229. else
  230. Ptr = Ptr->iLink;
  231. }
  232. else if (Ptr ->jVertex == CurIndex)
  233. {
  234. if (VertexArray[Ptr->iVertex].Flag == No){
  235. return Ptr->iVertex;
  236. }
  237. else
  238. Ptr = Ptr->jLink;
  239. }
  240. }
  241. if (Ptr == NULL) { return N; }
  242. }
  243.  
  244. template <typename Type, int N>
  245. void MulAdjacencyList <Type, N>::DFS(int x, const Type& Value) //x为起始的下标,Value为查找的值
  246. {
  247. if (VertexArray[x].Data == Value)
  248. {
  249. Temp.push_back(x);
  250. }
  251. VertexArray[x].Flag = Yes;
  252. int TempIndex = NextIndex(x);
  253. while (TempIndex != N)
  254. {
  255. DFS(TempIndex, Value);
  256. TempIndex = NextIndex(x);
  257. }
  258. for (vector <int>::const_iterator i = A.Temp.begin(); i != A.Temp.end(); ++i) //打印找到的元素
  259. cout << *i << endl;
  260. }
  261.  
  262. template <typename Type, int N>
  263. void MulAdjacencyList <Type, N>::BFSHelper(set <int> SourceList,const Type& Value)
  264. {
  265. if (!SourceList.empty())
  266. {
  267. for (set <int>::const_iterator i = SourceList.begin(); i != SourceList.end(); ++i)
  268. {
  269. VertexArray[*i].Flag = Yes;
  270. if (VertexArray[*i].Data == Value)
  271. Temp.push_back(*i);
  272. }
  273. for (set <int>::const_iterator i = SourceList.begin(); i != SourceList.end(); ++i)
  274. {
  275. AllNextIndex(*i);
  276. }
  277. SourceList = TempList;
  278. TempList.clear();
  279. BFSHelper(SourceList, Value);
  280. }
  281. }
  282.  
  283. template <typename Type, int N>
  284. void MulAdjacencyList <Type, N>::BFS(int x, const Type& Value)
  285. {
  286. set <int> Set;
  287. Set.insert(x);
  288. BFSHelper(Set, Value);
  289. }
  290. #endif

大类的代码有点乱,先挖个坑以后有空再来填上,希望对各位和自己有帮助。

图的邻接多重表和搜索(C++版本)的更多相关文章

  1. 图->存储结构->邻接多重表

    文字描述 邻接多重表是无向图的另一种链式存储结构. 虽然邻接表是无向图的一种很有效的存储结构,在邻接表中容易求得顶点和边的各种信息. 但是,在邻接表中每一条边(vi,vj)有两个结点,分别在第i个和第 ...

  2. 数据结构学习笔记05图 (邻接矩阵 邻接表-->BFS DFS、最短路径)

    数据结构之图 图(Graph) 包含 一组顶点:通常用V (Vertex) 表示顶点集合 一组边:通常用E (Edge) 表示边的集合 边是顶点对:(v, w) ∈E ,其中v, w ∈ V 有向边& ...

  3. 数据结构之---C语言实现图的邻接表存储表示

    // 图的数组(邻接矩阵)存储表示 #include <stdio.h> #include <stdlib.h> #include <string.h> #defi ...

  4. 图的邻接表存储表示(C)

    //---------图的邻接表存储表示------- #include<stdio.h> #include<stdlib.h> #define MAX_VERTEXT_NUM ...

  5. 图的邻接表存储 c实现

    图的邻接表存储 c实现 (转载) 用到的数据结构是 一个是顶点表,包括顶点和指向下一个邻接点的指针 一个是边表, 数据结构跟顶点不同,存储的是顶点的序号,和指向下一个的指针 刚开始的时候把顶点表初始化 ...

  6. 基于visual Studio2013解决算法导论之053图的邻接表表示

     题目 图的邻接表表示 解决代码及点评 // 图的邻接表表示.cpp : 定义控制台应用程序的入口点. // #include <iostream> #include <sta ...

  7. c_数据结构_图_邻接表

    课程设计------邻接表 图的遍历实现课程设计:https://files.cnblogs.com/files/Vera-y/图的遍历_课程设计.zip #include<stdio.h> ...

  8. 图论——图的邻接表实现——Java语言(完整demo)

    1.图的简单实现方法——邻接矩阵 表示图的一种简单的方法是使用一个一维数组和一个二维数组,称为领接矩阵(adjacent matrix)表示法. 对于每条边(u,v),置A[u,v]等于true:否则 ...

  9. 稀疏图(邻接链表),并查集,最短路径(Dijkstra,spfa),最小生成树(kruskal,prim)

    全部函数通过杭电 1142,1162,1198,1213等题目测试. #include<iostream> #include<vector> #include<queue ...

随机推荐

  1. Activity之间传递参数(三)

    ------siwuxie095 传递值对象,即自定义的有数据类型的对象 1.首先 new 一个 class:User,用于创建自定义对象,同时右键 Generate 出 Constructor.se ...

  2. MM常用表

    Table 表描述 MKPF 物料凭证抬头 MSEG 物料凭证段

  3. atoi()函数

    原型:int  atoi (const  char  *nptr) 用法:#include  <stdlib.h> 功能:将字符串转换成整型数:atoi()会扫描参数nptr字符串,跳过前 ...

  4. (转)jQuery EasyUI Tree - TreeGrid动态加载子节点

    有时我们已经得到充分的分层树形网格(TreeGrid)的数据. 我们还想让树形网格(TreeGrid)按层次惰性加载节点. 首先,只加载顶层节点. 然后点击节点的展开图标来加载它的子节点. 本教程展示 ...

  5. 加载音频Audio

    var cameraAudio = new Audio(); cameraAudio.src = 'camera.wav'; // 设置音频对象的属性,预加载视频 var options_audio ...

  6. HTML超标记语言

     Html超文本标记语言,负责描绘Web世界的骨架. 〇.工具 http;//www.w3cchool.com.cn 一.Tim Bemers Lee 万维网之父: Html设计者: W3C创始人: ...

  7. 【如何快速的开发一个完整的iOS直播app】(播放篇)

    原文转自:袁峥Seemygo    感谢分享.自我学习 前言 在看这篇之前,如果您还不了解直播原理,请查看上篇文章如何快速的开发一个完整的iOS直播app(原理篇) 开发一款直播app,集成ijkpl ...

  8. Python 字符串分割的方法

    在平时工作的时候,发现对于字符串分割的方法用的比较多,下面对分割字符串方法进行总结一下:第一种:split()函数split()函数应该说是分割字符串使用最多的函数用法:str.split('分割符' ...

  9. cassandra-执行请求入口函数

    参考 http://ju.outofmemory.cn/entry/115864 org.apache.cassandra.transport.Message中静态Dispatcher的 channe ...

  10. 了解Hadoop和大数据

    1. 场景: 现在人产生数据越来越快,机器则更快,所以需要另外的一种处理数据的方法.   硬盘容量增加,但是性能没跟上,解决办法是将数据分到多块硬盘,然后同时读取. 问题:     硬件问题 -- 复 ...