1. /*图的存储及遍历*/
  2. #include<iostream>
  3. using namespace std;
  4. //-----------------------------------
  5. //邻接矩阵的存储及深度和广度遍历
  6. //-----------------------------------
  7.  
  8. /*邻接矩阵的类型定义*/
  9. #define MAX 10000000
  10. #define MAX_VERTEX_NUM 20
  11. typedef enum{ DG,DN,UDG,UDN }GraphKind;//有向图,有向网,无向图,无向网
  12. typedef struct
  13. {
  14. char vexs[MAX_VERTEX_NUM];//用一维数组存储顶点信息
  15. int edges[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//用二维数组充当矩阵,来存储顶点边的信息
  16. int vexnum,edgenum;//顶点树和边数
  17. GraphKind kind;//图的种类
  18. }MGraph;
  19.  
  20. /*构造无向图的邻接矩阵*/
  21. void CreateUDG_AM(MGraph &G,int n,int e)
  22. {
  23. G.vexnum=n;
  24. G.edgenum=e;
  25.  
  26. int i,j,k;
  27. for(i=;i<n;i++)
  28. cin>>G.vexs[i];//输入顶点信息
  29.  
  30. for(i=;i<n;i++)
  31. for(j=;j<n;j++)
  32. G.edges[i][j]=;//将矩阵初始化为0
  33.  
  34. for(k=;k<e;k++)
  35. {
  36. cin>>i>>j;//这里只用输入对称的边就行,也就是输入下矩阵或是上矩阵
  37. G.edges[i][j]=G.edges[j][i]=;//输入边的信息
  38. }
  39. }
  40.  
  41. /****************************无向图的深度优先遍历************************/
  42. int visited[MAX_VERTEX_NUM];
  43.  
  44. void DF_AM(MGraph &G,int i)
  45. {
  46. int j;
  47. cout<<G.vexs[i]<<" ";
  48. visited[i]=;
  49. for(j=;j<G.vexnum;j++)
  50. {
  51. if((G.edges[i][j])==&&(visited[j])==)
  52. DF_AM(G,j);
  53. }
  54. }
  55.  
  56. void DF_Traverse_AM(MGraph &G)
  57. {
  58. int i;
  59. for(i=;i<G.vexnum;i++)
  60. {
  61. visited[i]=;
  62. }
  63. for(i=;i<G.vexnum;i++)
  64. {
  65. if(!visited[i])
  66. DF_AM(G,i);
  67. }
  68. }
  69.  
  70. /*********************无向图的广度优先遍历*****************************/
  71.  
  72. //循环队列的类型定义
  73. const int Queue_Size=;
  74.  
  75. typedef struct circlQueue
  76. {
  77. int *elem;
  78. int rear;
  79. int front;
  80. int queueSize;
  81. }circlQueue;
  82.  
  83. //初始化
  84. void initQueue_C(circlQueue &Q)
  85. {
  86. Q.elem=new int[Queue_Size];
  87. Q.front=Q.rear=;//首尾指针相等说明队列为空。
  88. Q.queueSize=Queue_Size;
  89. }
  90.  
  91. //入队列
  92. void enterQueue_C(circlQueue &Q,int x)
  93. {
  94. if(((Q.rear+)%Q.queueSize)==Q.front)//判断栈满的情况
  95. cout<<"Queue OverFlow!";
  96. Q.elem[Q.rear]=x;
  97. Q.rear=(Q.rear+)%Queue_Size;//尾指针应以此种方式加1,才会实现循环队列。
  98. }
  99.  
  100. //出队列
  101. char outputQueue_C(circlQueue &Q)
  102. {
  103. int e;
  104. if(Q.rear==Q.front)
  105. cout<<"Queue Empty";
  106. e=Q.elem[Q.front];
  107. Q.front=(Q.front+)%Q.queueSize;;//头指针应以此种方式加1,才会实现循环队列。
  108. return e;
  109. }
  110. //广度遍历
  111. void BF_Traverse_AM(MGraph &G)
  112. {
  113. int i,j,v;
  114. for(i=;i<G.vexnum;i++)
  115. visited[i]=;
  116. circlQueue Q;
  117. initQueue_C(Q);//队列实现了“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问
  118. for(i=;i<G.vexnum;i++)
  119. {
  120. if(!visited[i])
  121. {
  122. cout<<G.vexs[i]<<" ";
  123. visited[i]=;
  124. enterQueue_C(Q,i);
  125. while(Q.front!=Q.rear)
  126. {//这个循环是将队列里面的顶点取出来,然后进行下面的for循环
  127. v=outputQueue_C(Q);
  128. for(j=;j<G.vexnum;j++)
  129. {//这个循环是将顶点的全部邻接点依次访问并且入队列
  130. if(G.edges[v][j]&&(!visited[j]))
  131. {
  132. cout<<G.vexs[j]<<" ";
  133. visited[j]=;
  134. enterQueue_C(Q,j);
  135. }
  136. }
  137. }
  138. }
  139. }
  140. }
  141.  
  142. //-----------------------------------------------
  143. //邻接表的存储及深度和广度遍历
  144. //-----------------------------------------------
  145. typedef struct EdgeNode
  146. {//边表结点的定义
  147. int adjvex;//存放邻接点在顶点表中的位置
  148. struct EdgeNode * nextedge;//指向下一个边表结点
  149. int weight;
  150. }EdgeNode;
  151.  
  152. typedef struct VexNode
  153. {//顶点表结点的定义
  154. char vex;//存放顶点信息
  155. EdgeNode * firstedge;//指向第一个边表结点
  156. }VexNode;
  157.  
  158. typedef struct
  159. {//顶点表的定义
  160. VexNode vexs[MAX_VERTEX_NUM];
  161. int vexnum,edgenum;
  162. GraphKind kind;
  163. }LGraph;
  164.  
  165. /*构造有向图的邻接表*/
  166. void CreateDG_AL(LGraph &G,int n,int e)
  167. {
  168. int i,j,k;
  169. G.vexnum=n;
  170. G.edgenum=e;
  171. G.kind=DG;
  172. for(i=;i<n;i++)
  173. {
  174. cin>>G.vexs[i].vex;
  175. G.vexs[i].firstedge=NULL;//初始化为空
  176. }
  177. for(k=;k<e;k++)
  178. {
  179. EdgeNode *p;
  180. cin>>i>>j;
  181. p=new EdgeNode;
  182. p->adjvex=j;
  183. p->nextedge=G.vexs[i].firstedge;
  184. G.vexs[i].firstedge=p;//采用头插法
  185. }
  186. }
  187.  
  188. /*********************有向图的深度优先遍历**************************/
  189. void DF_AL(LGraph &G,int v)
  190. {
  191. int j;
  192. EdgeNode *p;
  193. cout<<G.vexs[v].vex<<" ";
  194. visited[v]=;
  195. for(p=G.vexs[v].firstedge;p;p=p->nextedge)
  196. {
  197. j=p->adjvex;
  198. if(!visited[j])
  199. DF_AL(G,j);
  200. }
  201. }
  202.  
  203. void DF_Traverse_AL(LGraph &G)
  204. {
  205. int i;
  206. for(i=;i<G.vexnum;i++)
  207. {
  208. visited[i]=;
  209. }
  210. for(i=;i<G.vexnum;i++)
  211. {
  212. if(!visited[i])
  213. DF_AL(G,i);
  214. }
  215. } /* 何问起 hovertree.com */
  216. /*********************有向图的广度优先遍历**************************/
  217. void BF_Traverse_AL(LGraph &G)
  218. {
  219. int i,j,v;
  220. EdgeNode *p;
  221. for(i=;i<G.vexnum;i++)
  222. visited[i]=;
  223. circlQueue Q;
  224. initQueue_C(Q);//队列实现了“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问
  225. for(i=;i<G.vexnum;i++)
  226. {
  227. if(!visited[i])
  228. {
  229. cout<<G.vexs[i].vex<<" ";
  230. visited[i]=;
  231. enterQueue_C(Q,i);
  232. while(Q.front!=Q.rear)
  233. {//这个循环是将队列里面的顶点取出来,然后进行下面的for循环
  234. v=outputQueue_C(Q);
  235. for(p=G.vexs[v].firstedge;p;p=p->nextedge)
  236. {//这个循环是将顶点的全部邻接点依次访问并且入队列
  237. j=p->adjvex;
  238. if(!visited[j])
  239. {
  240. cout<<G.vexs[j].vex<<" ";
  241. visited[j]=;
  242. enterQueue_C(Q,j);
  243. }
  244. }
  245. }
  246. }
  247. }
  248. }
  249. void main()
  250. {
  251. /*MGraph G;
  252. CreateUDG_AM(G,6,6);
  253. DF_Traverse_AM(G);
  254. cout<<endl;
  255. BF_Traverse_AM(G);*/
  256.  
  257. LGraph G;
  258. CreateDG_AL(G,,);
  259. DF_Traverse_AL(G);
  260. cout<<endl;
  261. BF_Traverse_AL(G);
  262. }

写这个程序给我的感觉就是乱,思路不是很清晰,遍历的逻辑关系还掌握的不是很熟,只是大概知道是这么回事,但是让自己去写的话,可能就写不出来了!还是要加大对遍历的熟悉程度才行啊!

PS:另外推荐一个让大家真正练手的网站:猪八戒威客网,在这里可以按自己的能力去接一些程序设计的任务。我觉得这是一种很不错的学习方法,当你接了别人的任务,无形中就给了自己压力和动力,然后就会主动的去查询资料,分析问题,可能会历经艰辛才能解决问题,但这中间的过程是很珍贵的,你会通过自己的努力学到很多课本上没有学到的东西,也能过一回需求分析的瘾,真实的体会到和客户进行交流的诸多“纠结”,最后,如果你的努力得到客户的认可,可以获得一笔小小的佣金,当做对自己的奖励,更重要的是,通过做任务,你能体会到自己存在的价值感和对自己能力的肯定!

推荐:http://www.cnblogs.com/roucheng/p/cpphong.html

图的存储及遍历 深度遍历和广度遍历 C++代码实现的更多相关文章

  1. 重新整理数据结构与算法(c#)—— 图的深度遍历和广度遍历[十一]

    参考网址:https://www.cnblogs.com/aoximin/p/13162635.html 前言 简介图: 在数据的逻辑结构D=(KR)中,如果K中结点对于关系R的前趋和后继的个数不加限 ...

  2. 图的存储,搜索,遍历,广度优先算法和深度优先算法,最小生成树-Java实现

    1)用邻接矩阵方式进行图的存储.如果一个图有n个节点,则可以用n*n的二维数组来存储图中的各个节点关系. 对上面图中各个节点分别编号,ABCDEF分别设置为012345.那么AB AC AD 关系可以 ...

  3. C++编程练习(9)----“图的存储结构以及图的遍历“(邻接矩阵、深度优先遍历、广度优先遍历)

    图的存储结构 1)邻接矩阵 用两个数组来表示图,一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中边或弧的信息. 2)邻接表 3)十字链表 4)邻接多重表 5)边集数组 本文只用代码实现用 ...

  4. 【数据结构】4.1图的创建及DFS深度遍历(不完善)

    声明:本代码仅供参考,根本就不是正确代码(至少在我看来,有很多BUG和不完美的地方) 图的存储方式选择为邻接表,并且headNode只是来存储一个链表的Node首地址额 总之这个代码写的很垃圾呀很垃圾 ...

  5. 【algo&ds】6.图及其存储结构、遍历

    1.什么是图 图表示"多对多"的关系 包含 一组顶点:通常用 V(Vertex)表示顶点集合 一组边:通常用 E(Edge)表示边的集合 边是顶点对:(v,w)∈ E,其中 v,w ...

  6. 【lhyaaa】图的存储&遍历

    呀,图真是一个令人头疼而又很重要的东西.在现实生活中,我们有很多的问题都不能用树来实现,所以烦人啊不伟大的图就出现了—— 图的存储 没有存储哪来的操作,所以存储是最基础的呢. 邻接矩阵 我们对于图的存 ...

  7. 图的存储与遍历C++实现

    1.图的存储 设点数为n,边数为m 1.1.二维数组 方法:使用一个二维数组 adj 来存边,其中 adj[u][v] 为 1 表示存在 u到 v的边,为 0 表示不存在.如果是带边权的图,可以在 a ...

  8. 数据结构作业——图的存储及遍历(邻接矩阵、邻接表+DFS递归、非递归+BFS)

    邻接矩阵存图 /* * @Author: WZY * @School: HPU * @Date: 2018-11-02 18:35:27 * @Last Modified by: WZY * @Las ...

  9. 多级树的深度遍历与广度遍历(Java实现)

    目录 多级树的深度遍历与广度遍历 节点模型 深度优先遍历 广度优先遍历 多级树的深度遍历与广度遍历 深度优先遍历与广度优先遍历其实是属于图算法的一种,多级树可以看做是一种特殊的图,所以多级数的深/广遍 ...

随机推荐

  1. 使用Chef管理windows集群

    但凡服务器上了一定规模(百台以上),普通的ssh登录管理的模式就越来越举步维艰.试想Linux发布了一个高危漏洞的补丁,你要把手下成百上千台机器都更新该补丁,如果没有一种自动化方式,那么至少要耗上大半 ...

  2. IOS 手势-轻点、触摸、手势、事件

    1.概念 手势是从你用一个或多个手指接触屏幕时开始,直到手指离开屏幕为止所发生的所有事件.无论手势持续多长时间,只要一个或多个手指仍在屏幕上,这个手势就存在. 触摸是指把手指放到IOS设备的屏幕上,从 ...

  3. java加密-解密小结

    加密算法可以分为 双向加密(对称加密.不对称加密) 单向加密(不可逆加密)—— MD5.sha.hmac... 在对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密 有: ...

  4. Redis总结笔记(二):C#连接Redis简单例子

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/113.html?1455860686 注:C#在调用Redis是不要使用S ...

  5. Java-继承,多态练习0922-06

    编写一个Shape类,具有属性:周长和面积: 定义其子类三角形和矩形,分别具有求周长的方法. 定义主类E,在其main方法中创建三角形和矩形类的对象, 并赋给Shape类的对象a.b,使用对象a.b来 ...

  6. NodeJS系列~第四个小例子,NodeJs处理Get请求和Post请求

    返回目录 说在前 对于HTTP请求来说,我们通常使用的是Get和Post,除此之外还有put,delete等,而对于get来说,比较lightweight,只是对字符串的传输,它会被添加到URL地址里 ...

  7. EF架构~CodeFirst生产环境的Migrations

    回到目录 Migrations即迁移,它是EF的code first模式出现的产物,它意思是说,将代码的变化反映到数据库上,这种反映有两种环境,一是本地开发环境,别一种是服务器的生产环境,本地开发环境 ...

  8. 03- Shell脚本学习--字符串和数组

    字符串 字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号,也可以不用引号.单双引号的区别跟PHP类似: 单双引号的区别: 双 ...

  9. PHP性能优化工具–xhprof安装

    PHP性能优化工具–xhprof安装,这里我先贴出大致的步骤: 1.获取xhprof 2.编译前预处理 3.编译安装 4.配置php.ini 5.查看运行结果 那么下面我们开始安装xhprof工具吧: ...

  10. 关于C#中的线程重启的问题

    首先不管是C#也好,还是java也好,对于已经Abort的线程是无法再次Start的,除非是声明私有变量new一个新的线程,网上也有很多人说可以Suspend挂起线程,然后再Resume继续,但是相信 ...