数据结构-图内容总结
数据结构-图内容总结
- 一、图的两种常用存储结构
- 二、图的两种遍历方式
- 三、最短路径的两种算法
- 四、最小生成树的两种算法
- 五、拓扑排序
- 六、关键路径
一、图的两种常用存储结构
邻接矩阵和邻接表存储的都是边的信息,顶点类还需要单独定义和实现。
- 邻接矩阵
特点:无向图中为对称矩阵,适合存储稠密图。 - 邻接表
特点:适合存储稀疏图。
二、图的两种遍历方式
深度优先遍历(DFS)
类似于树的先序遍历,采用递归的方法。(以邻接矩阵为例)void CMap::depthFirstTraverse(int nodeIndex){//输出顶点值cout<<m_pNodeArray[nodeIndex].m_cData<<" ";//设置当前节点为已经遍历过m_pNodeArray[nodeIndex].m_bIsVisited = true;//找到与当前节点连接的节点(还需要未被遍历过)进行遍历for(int i =0;i<m_iCapacity;i++){if(m_pMatrix[nodeIndex*m_iCapacity+i] && !m_pNodeArray[i].m_bIsVisited){depthFirstTraverse(i);}} }
广度优先遍历
使用队列存储即将访问的节点,与树的层序遍历类似。(以邻接矩阵为例)void CMap::breadthFirstTraverse(int nodeIndex){queue<int> queue1;queue1.push(nodeIndex);//将起始节点压入堆栈while(!queue1.empty()){ int temp = queue1.front(); queue1.pop();//取出并删除堆栈第一个节点if(!m_pNodeArray[temp].m_bIsVisited){cout<<m_pNodeArray[temp].m_cData<<" "; //将该节点访问状态设置为truem_pNodeArray[temp].m_bIsVisited = true;//找到与该节点相连且未被访问过的节点,压入队列下次访问for(int i =0;i<m_iCapacity;i++){if(m_pMatrix[temp*m_iCapacity+i] && !m_pNodeArray[i].m_bIsVisited){queue1.push(i);}}}} }
三、最短路径的两种算法
Dijkstra算法
算法的原理这个视频讲的非常清楚B站Dijkstra算法,大概意思是 每次从未确定的顶点中选择一个 源点到未确定顶点集合中cost最小的点,更新与它相连的其他最小cost 并 将 它的确定状态设置为true,直到遍历到终点。int CMap::dijkstra(int start, int end) {int value[m_iCapacity]; //记录源点到各个点的最小costfor(int i = 0;i<m_iCapacity;i++){value[i] = 100; //设置初值为一个很大的值}value[start] = 0;for(int i=0;i<m_iCapacity-1;i++){int min = 100; //记录每次int min_index;for(int j = 0;j<m_iCapacity;j++){//寻找未确定的顶点集合中cost的最小值if(value[j]<min && !m_pNodeArray[j].m_bIsVisited){min = value[j];min_index = j;}}m_pNodeArray[min_index].m_bIsVisited = true;//更新与最小点连接的其他点的最小cost for(int j = 0;j<m_iCapacity;j++){if(!m_pNodeArray[j].m_bIsVisited && m_pMatrix[min_index*m_iCapacity+j]>0)if(value[min_index]+m_pMatrix[min_index*m_iCapacity+j]<value[j]){value[j] = value[min_index]+m_pMatrix[min_index*m_iCapacity+j];}}}return value[end]; }
弗洛伊德(Floyed)算法
这个视频B站视频Floyed算法也讲的比较明白,大概思想是遍历每个顶点,更新以当前顶点为中间点的最小cost。比如有ABCD四个点,遍历A时比较 B到C的最小cost 和 B到A的最小cost+A到C的最小cost 两者哪个更小。最终返回起始点到终点的最小cost即可。int CMap::floyed(int start, int end) {int D[m_iCapacity*m_iCapacity]; //存储两点之间cost最小值int P[m_iCapacity*m_iCapacity]; //存储两点之间经过的最后一个顶点//初始化 初值为很大的数for(int i =0;i<m_iCapacity*m_iCapacity;i++){if(m_pMatrix[i]) D[i] = m_pMatrix[i];else D[i] = 100;P[i] = i%m_iCapacity;}//以i为中间点,从j到k的costfor(int i =0;i<m_iCapacity;i++){for(int j=0;j<m_iCapacity;j++){for(int k=0;k<m_iCapacity;k++){if(D[j*m_iCapacity+i]+D[i*m_iCapacity+k]<D[j*m_iCapacity+k]){//当从j到k经过i的cost值最小时,更新从j到k的最小值D[j*m_iCapacity+k] = D[j*m_iCapacity+i]+D[i*m_iCapacity+k];//更新从j到k经过的顶点坐标P[j*m_iCapacity+k] = P[j*m_iCapacity+i] ;}}}}//输出路径int j = end;cout<<end<<" ";while(start!=j){cout<<P[j*m_iCapacity+start]<<" ";j = P[j*m_iCapacity+start];}cout<<endl;//返回最小costreturn D[start*m_iCapacity+end]; }
四、最小生成树的两种算法
最小生成树:无回路、V个顶点有V-1条边
最小生成树:包含全部顶点、V-1条边都在图里、任加一条边就会构成回路。
最小生成树: 边的权重之和最小。
B站视频最小生成树
Prim普利姆算法
和Dijkstra很像,但也有不同之处
Prim每次比较的是i到j的最小权值,而Dijkstra比较的是从起点到i的最小权值+i到j的最小权值。for(int j = 0;j<m_iCapacity;j++){if(!m_pNodeArray[j].m_bIsVisited && m_pMatrix[min_index*m_iCapacity+j]>0)//这里的比较不需要加value[min_index]if(m_pMatrix[min_index*m_iCapacity+j]<value[j]){value[j] = m_pMatrix[min_index*m_iCapacity+j];}}
Kruskal克鲁斯卡尔算法
主要思想:将权值按从小到大排序,从小到大逐个生成图。如果新插入的权值对应的边使得图变成环,就不加入这个权值,直到插入的边的个数为V-1即可。
如何判断图成为环:维护一个顶点个数长度的数组,初始化为节点自身的编号,数组内容记录更新构建最小生成树过程中的根节点,如果一条边起点和终点的根节点一样则会形成环。
如图所示,边排序好之后为{[E,F] [C,D] [D,E] [C,F] [B,F]…}- 最小权值为2,E[E]!=F[F],选择EF,将起点为F的全部改成E ~~~~~~~ E对应的起点为[E],F对应的起点为[E]
- 最小权值为3,C[C]!=D[D],选择CD,将起点为D的全部改成C ~~~~~~ C对应的起点为[C],D对应的起点为[C]
- 最小权值为4,D[C]!=E[E],选择DE,将起点为E的全部改成C ~~~~~~ F、E起点都改为[C]
- 最小权值为5,C[C]==E[C],C和E对应的起点都是C,不选择CE
- 最小权值为6,C[C]==F[C],C和F对应的起点都是C,不选择CF
- 最小权值为7,B[B]!=F[C],选择BF,将起点为C的全部改为B~~~~~~~ C对应的起点(E、F、C、D)都改为[B]
- 最小权值为8,E[B]!=G[G],选择EG,将起点为G的全部改为B~~~~~~ G对应的起点都改为[B]
- 最小权值为9,F[B]==G[B],不选择FG
- 最小权值为12,A[A]!=B[B],选择AB,将起点B的全部改为A~~~~~~~~~ B(B、C、D、E、F、G)对应的起点都改为[A]
~~~~~~ A~G共7个顶点,选择了6条边即可完成选择。
五、拓扑排序
看的视频:浙江大学-数据结构P99
- 一些名词
- AOV网:人们常用有向图来描述和分析一项工程的计划和实施过程,一个工程常被分为多个小的子工程,这些子工程被称为活动(Activity),在有向图中若以顶点表示活动,有向边表示活动之间的先后关系。有向无环图才是合理的。
- 拓扑序列:顶点活动网中将活动按发生的先后次序进行的一种排列。 拓扑排序,是对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。
- 基本思想:维护一个队列,一开始为空。首先将入度为0的点加入队列中,每操作并弹出一个顶点,将与该顶点相连的顶点入度-1,并判断入度是否为0,如果入度为0则加入队列中,直至队列为空。
六、关键路径
- AOE网:在带权有向图中以顶点表示事件,有向边表示活动,边上的权值表示该活动持续的时间。
- 关键路径:路径上各个活动所持续时间之和称为路径长度,则从源点到汇点具有在最大长度的路径即为关键路径。
最大长度路径即加工工序中最耗时的部分,关键路径也就是求加工工序正常完成的最短时间。
~~~~~~ 看的视频:浙江大学-数据结构P100
~~~~~~ 可以看视频进行理解。
数据结构-图内容总结相关推荐
- 数据结构--图(Graph)详解(二)
数据结构–图(Graph)详解(二) 文章目录 数据结构--图(Graph)详解(二) 一.图的存储结构 1.图的顺序存储法 2.图的邻接表存储法 3.图的十字链表存储法 4.图的邻接多重表存储法 二 ...
- 四色着色问题 c语言编程,数据结构-图着色问题
7-38 图着色问题 (25 分) 图着色问题是一个著名的NP完全问题.给定无向图G=(V,E),问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色? 但本题并不是要 ...
- 数据结构—图及其应用(交通问题,实现最短路径、最短时间、最少费用查询)
数据结构-图及其应用(交通问题,实现最短路径.最短时间.最少费用查询) 1.任务描述 (1).任务: 设计一个城市交通咨询模拟系统,利用该系统实现至少两种最优决策:最短路程到达.最省时到达等线路规划. ...
- 866数据结构重点内容
湖大计学考研系列文章目录 22湖南大学计算机学硕上岸经验 22湖南大学 866 数据结构真题(回忆版) 866数据结构重点内容 866 数据结构模拟题(一)及解析 866数据结构笔记 - 第一章 绪论 ...
- 数据结构——图——克鲁斯卡尔(Kruskal)算法
数据结构--图--克鲁斯卡尔(Kruskal)算法 同样的思路,我们也可以直接就以边为目标去构建,因为权值是在边上,直接去找最小权值的边来构建生成树也是很自然的想法,只不过构建时要考虑是否会形成环路而 ...
- 数据结构--图(Graph)详解(四)
数据结构–图(Graph)详解(四) 文章目录 数据结构--图(Graph)详解(四) 一.图中几个NB的算法 1.普里姆算法(Prim算法)求最小生成树 2.克鲁斯卡尔算法(Kruskal算法)求最 ...
- 数据结构--图(Graph)详解(三)
数据结构–图(Graph)详解(三) 文章目录 数据结构--图(Graph)详解(三) 一.深度优先生成树和广度优先生成树 1.铺垫 2.非连通图的生成森林 3.深度优先生成森林 4.广度优先生成森林 ...
- 数据结构--图(Graph)详解(一)
数据结构–图(Graph)详解(一) 文章目录 数据结构--图(Graph)详解(一) 一.图的基本概念 1.图的分类 2.弧头和弧尾 3.入度和出度 4.(V1,V2) 和 < V1,V2 & ...
- 【数据结构(C语言)】数据结构-图
图 文章目录 图 一.基本概念 1.图的定义 2.约定符号 3.分类 4.子图 5.路 6.其他术语 7.ADT 二.存储结构 1.邻接矩阵(数组) 2.邻接表 三.基本算法 1.遍历 2.求无向图的 ...
最新文章
- 王树彤IT美女七年磨一剑
- 【BZOJ3926】[Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机
- 幂函数与指数函数的区别
- NVIDIA Tesla/Quadro和GeForce GPU的比较
- 创建javascript对象的几种方式
- 【国内首家!】阿里云专有云通过商用密码应用安全性评估
- 我那个37岁的大神朋友,后续
- 李维说他跳槽了,那我以后也不是Borland的Fans了?
- scala 冒泡排序
- 7-5 BCD解密 (10 分)
- 作用JavaScript访问和操作数据库
- socket通信问题
- C Primer Plus(6) 中文版 第6章 C控制语句:循环 6.2 while语句
- 单片机C语言流水灯花样编程,单片机C语言程序设计:花样流水灯
- R语言-岭回归的代码与案例解读
- 加速度计和陀螺仪指南
- 「PS-CC2019新版教程」套索工具-基础篇
- 电子元器件贸易如何应用采购管理系统,做好采购订单交期管理?
- .NET主流的ORM框架
- android输入法框架分析,Android与iOS输入法开发框架比较谈
热门文章
- html点击展开盒子变大,JS实现点击按钮控制Div变宽、增高及调整背景色的方法
- 夏天水果店怎么打理,如何打理好一个水果店
- python文本聚类_python 文本聚类算法
- 我是深圳南山的集体户口,要将我老婆的户口随迁入深圳 没有房产,可以办深圳人才中心的集体户口吗
- Google PR值
- Python之生成器详解
- 红米 android8 刷机,小米红米5 plus(安卓8.0)手机刷机图文教程工具分享,快速一键刷机...
- 亚马逊后台网页提示HTTP Status 400 – Bad Request无法登陆的解决办法
- MSYS2 瘦身小攻略
- QQ和360干起来了,中国互联网2大服务商进行白刃战