图的存储及遍历 深度遍历和广度遍历 C++代码实现

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

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

/*图的存储及遍历*/ #include<iostream> using namespace std; //----------------------------------- //邻接矩阵的存储及深度和广度遍历 //-----------------------------------  /*邻接矩阵的类型定义*/ #define MAX 10000000 #define MAX_VERTEX_NUM 20  typedef enum{ DG,DN,UDG,UDN }GraphKind;//有向图,有向网,无向图,无向网  typedef struct { char vexs[MAX_VERTEX_NUM];//用一维数组存储顶点信息  int edges[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//用二维数组充当矩阵,来存储顶点边的信息  int vexnum,edgenum;//顶点树和边数  GraphKind kind;//图的种类  }MGraph; /*构造无向图的邻接矩阵*/ void CreateUDG_AM(MGraph &G,int n,int e) { G.vexnum=n; G.edgenum=e; int i,j,k; for(i=0;i<n;i++) cin>>G.vexs[i];//输入顶点信息  for(i=0;i<n;i++) for(j=0;j<n;j++) G.edges[i][j]=0;//将矩阵初始化为0  for(k=0;k<e;k++) { cin>>i>>j;//这里只用输入对称的边就行,也就是输入下矩阵或是上矩阵  G.edges[i][j]=G.edges[j][i]=1;//输入边的信息   } } /****************************无向图的深度优先遍历************************/ int visited[MAX_VERTEX_NUM]; void DF_AM(MGraph &G,int i) { int j; cout<<G.vexs[i]<<" "; visited[i]=1; for(j=0;j<G.vexnum;j++) { if((G.edges[i][j])==1&&(visited[j])==0) DF_AM(G,j); } } void DF_Traverse_AM(MGraph &G) { int i; for(i=0;i<G.vexnum;i++) { visited[i]=0; } for(i=0;i<G.vexnum;i++) { if(!visited[i]) DF_AM(G,i); } } /*********************无向图的广度优先遍历*****************************/ //循环队列的类型定义  const int Queue_Size=100; typedef struct circlQueue { int *elem; int rear; int front; int queueSize; }circlQueue; //初始化  void initQueue_C(circlQueue &Q) { Q.elem=new int[Queue_Size]; Q.front=Q.rear=0;//首尾指针相等说明队列为空。  Q.queueSize=Queue_Size; } //入队列  void enterQueue_C(circlQueue &Q,int x) { if(((Q.rear+1)%Q.queueSize)==Q.front)//判断栈满的情况  cout<<"Queue OverFlow!"; Q.elem[Q.rear]=x; Q.rear=(Q.rear+1)%Queue_Size;//尾指针应以此种方式加1,才会实现循环队列。  } //出队列  char outputQueue_C(circlQueue &Q) { int e; if(Q.rear==Q.front) cout<<"Queue Empty"; e=Q.elem[Q.front]; Q.front=(Q.front+1)%Q.queueSize;;//头指针应以此种方式加1,才会实现循环队列。  return e; } //广度遍历  void BF_Traverse_AM(MGraph &G) { int i,j,v; for(i=0;i<G.vexnum;i++) visited[i]=0; circlQueue Q; initQueue_C(Q);//队列实现了“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问  for(i=0;i<G.vexnum;i++) { if(!visited[i]) { cout<<G.vexs[i]<<" "; visited[i]=1; enterQueue_C(Q,i); while(Q.front!=Q.rear) {//这个循环是将队列里面的顶点取出来,然后进行下面的for循环  v=outputQueue_C(Q); for(j=0;j<G.vexnum;j++) {//这个循环是将顶点的全部邻接点依次访问并且入队列  if(G.edges[v][j]&&(!visited[j])) { cout<<G.vexs[j]<<" "; visited[j]=1; enterQueue_C(Q,j); } } } } } } //----------------------------------------------- //邻接表的存储及深度和广度遍历 //-----------------------------------------------  typedef struct EdgeNode {//边表结点的定义  int adjvex;//存放邻接点在顶点表中的位置  struct EdgeNode * nextedge;//指向下一个边表结点  int weight; }EdgeNode; typedef struct VexNode {//顶点表结点的定义  char vex;//存放顶点信息  EdgeNode * firstedge;//指向第一个边表结点  }VexNode; typedef struct {//顶点表的定义   VexNode vexs[MAX_VERTEX_NUM]; int vexnum,edgenum; GraphKind kind; }LGraph; /*构造有向图的邻接表*/ void CreateDG_AL(LGraph &G,int n,int e) { int i,j,k; G.vexnum=n; G.edgenum=e; G.kind=DG; for(i=0;i<n;i++) { cin>>G.vexs[i].vex; G.vexs[i].firstedge=NULL;//初始化为空   } for(k=0;k<e;k++) { EdgeNode *p; cin>>i>>j; p=new EdgeNode; p->adjvex=j; p->nextedge=G.vexs[i].firstedge; G.vexs[i].firstedge=p;//采用头插法   } } /*********************有向图的深度优先遍历**************************/ void DF_AL(LGraph &G,int v) { int j; EdgeNode *p; cout<<G.vexs[v].vex<<" "; visited[v]=1; for(p=G.vexs[v].firstedge;p;p=p->nextedge) { j=p->adjvex; if(!visited[j]) DF_AL(G,j); } } void DF_Traverse_AL(LGraph &G) { int i; for(i=0;i<G.vexnum;i++) { visited[i]=0; } for(i=0;i<G.vexnum;i++) { if(!visited[i]) DF_AL(G,i); } } /* 何问起 hovertree.com */ /*********************有向图的广度优先遍历**************************/ void BF_Traverse_AL(LGraph &G) { int i,j,v; EdgeNode *p; for(i=0;i<G.vexnum;i++) visited[i]=0; circlQueue Q; initQueue_C(Q);//队列实现了“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问  for(i=0;i<G.vexnum;i++) { if(!visited[i]) { cout<<G.vexs[i].vex<<" "; visited[i]=1; enterQueue_C(Q,i); while(Q.front!=Q.rear) {//这个循环是将队列里面的顶点取出来,然后进行下面的for循环  v=outputQueue_C(Q); for(p=G.vexs[v].firstedge;p;p=p->nextedge) {//这个循环是将顶点的全部邻接点依次访问并且入队列  j=p->adjvex; if(!visited[j]) { cout<<G.vexs[j].vex<<" "; visited[j]=1; enterQueue_C(Q,j); } } } } } } void main() { /*MGraph G; CreateUDG_AM(G,6,6); DF_Traverse_AM(G); cout<<endl; BF_Traverse_AM(G);*/ LGraph G; CreateDG_AL(G,5,7); DF_Traverse_AL(G); cout<<endl; BF_Traverse_AL(G); } 

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

 

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/120468.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 矩阵卷积运算过程讲解「建议收藏」

    矩阵卷积运算过程讲解「建议收藏」在爬虫处理验证码的过程中接触到矩阵卷积运算,关于该类运算,记录一下自己的心得。理论知识在讲述卷积过程前,我们来了解一下卷积公式。根据离散二维卷积公式:其中A为被卷积矩阵,K为卷积核,B为卷积结果,该公式中,三个矩阵的排序均从0开始。现在对于上面卷积过程进行分析:我们用来做例子的A矩阵为m×m(3×3)二维矩阵(被卷积矩阵),K为n×n(2×2)的二维矩阵(卷积核)。卷……

    2022年10月29日
  • 新鲜出炉: IE8 beta1 的下载地址以及官方论坛

    新鲜出炉: IE8 beta1 的下载地址以及官方论坛

  • CANoe/CANalyzer诊断功能的深入理解以及CAPL诊断编程实现

    CANoe/CANalyzer诊断功能的深入理解以及CAPL诊断编程实现之前和大家分享了CANoe的基础使用(分析、仿真、测试、诊断),这篇文章将继续深入探讨如何使用CANoe/CANalyzer中的诊断功能。诊断用于在将ECU安装到系统之前或之后配置,维护,支持,控制和扩展ECU,例如,一辆车。诊断通常在请求-响应方案中执行:测试仪(客户端)向…

  • 【FPGA——基础篇】同步FIFO与异步FIFO——Verilog实现「建议收藏」

    FIFO是英文FirstInFirstOut的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。作用:FIFO一般用于不同时钟域之间的数据传输,比如FIFO的一端是AD数据采集,另一端是计算…

  • linux使用ps命令查看和控制进程_centos 查看进程

    linux使用ps命令查看和控制进程_centos 查看进程ps命令Linuxps(英文全拼:processstatus)命令用于显示当前进程的状态,类似于windows的任务管理器查看所有进程ps-A显示所有进程信息,连同命令行ps-

  • LTE学习笔记:频带、信道带宽和频点号EARFCN「建议收藏」

    LTE学习笔记:频带、信道带宽和频点号EARFCN「建议收藏」转自:https://blog.csdn.net/m_052148/article/details/513222601.频带(Band)所谓频带,指代的是一个频率的范围或者频谱的宽度,即无线解码器的最低工作频率至最高工作频率之间的范围,单位是Hz。为了方便起见,在LTE中,使用数字1-43来表示不同的频带(36101-V10.21.0版本协议),从而指代不同的频率范围。协议36101规…

    2022年10月11日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号