数据结构-图内容总结

  • 一、图的两种常用存储结构
  • 二、图的两种遍历方式
  • 三、最短路径的两种算法
  • 四、最小生成树的两种算法
  • 五、拓扑排序
  • 六、关键路径

一、图的两种常用存储结构

邻接矩阵和邻接表存储的都是边的信息,顶点类还需要单独定义和实现。

  1. 邻接矩阵
    特点:无向图中为对称矩阵,适合存储稠密图。
  2. 邻接表
    特点:适合存储稀疏图。

二、图的两种遍历方式

  1. 深度优先遍历(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);}}
    }
    
  2. 广度优先遍历
    使用队列存储即将访问的节点,与树的层序遍历类似。(以邻接矩阵为例)

    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);}}}}
    }
    

三、最短路径的两种算法

  1. 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];
    }
    
  2. 弗洛伊德(Floyed)算法
    这个视频B站视频Floyed算法也讲的比较明白,大概思想是遍历每个顶点,更新以当前顶点为中间点的最小cost。比如有ABCD四个点,遍历A时比较 B到C的最小costB到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站视频最小生成树

  1. 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];}}
    
  2. Kruskal克鲁斯卡尔算法
    主要思想:将权值按从小到大排序,从小到大逐个生成图。如果新插入的权值对应的边使得图变成环,就不加入这个权值,直到插入的边的个数为V-1即可。
    如何判断图成为环:维护一个顶点个数长度的数组,初始化为节点自身的编号,数组内容记录更新构建最小生成树过程中的根节点,如果一条边起点和终点的根节点一样则会形成环。

    如图所示,边排序好之后为{[E,F] [C,D] [D,E] [C,F] [B,F]…}

    1. 最小权值为2,E[E]!=F[F],选择EF,将起点为F的全部改成E ~~~~~~~        E对应的起点为[E],F对应的起点为[E]
    2. 最小权值为3,C[C]!=D[D],选择CD,将起点为D的全部改成C ~~~~~~      C对应的起点为[C],D对应的起点为[C]
    3. 最小权值为4,D[C]!=E[E],选择DE,将起点为E的全部改成C ~~~~~~       F、E起点都改为[C]
    4. 最小权值为5,C[C]==E[C],C和E对应的起点都是C,不选择CE
    5. 最小权值为6,C[C]==F[C],C和F对应的起点都是C,不选择CF
    6. 最小权值为7,B[B]!=F[C],选择BF,将起点为C的全部改为B~~~~~~~        C对应的起点(E、F、C、D)都改为[B]
    7. 最小权值为8,E[B]!=G[G],选择EG,将起点为G的全部改为B~~~~~~       G对应的起点都改为[B]
    8. 最小权值为9,F[B]==G[B],不选择FG
    9. 最小权值为12,A[A]!=B[B],选择AB,将起点B的全部改为A~~~~~~~~~          B(B、C、D、E、F、G)对应的起点都改为[A]

~~~~~~      A~G共7个顶点,选择了6条边即可完成选择。

五、拓扑排序

看的视频:浙江大学-数据结构P99

  1. 一些名词
  • AOV网:人们常用有向图来描述和分析一项工程的计划和实施过程,一个工程常被分为多个小的子工程,这些子工程被称为活动(Activity),在有向图中若以顶点表示活动,有向边表示活动之间的先后关系。有向无环图才是合理的。
  • 拓扑序列:顶点活动网中将活动按发生的先后次序进行的一种排列。 拓扑排序,是对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。
  1. 基本思想:维护一个队列,一开始为空。首先将入度为0的点加入队列中,每操作并弹出一个顶点,将与该顶点相连的顶点入度-1,并判断入度是否为0,如果入度为0则加入队列中,直至队列为空。

六、关键路径

  1. AOE网:在带权有向图中以顶点表示事件,有向边表示活动,边上的权值表示该活动持续的时间。
  2. 关键路径:路径上各个活动所持续时间之和称为路径长度,则从源点到汇点具有在最大长度的路径即为关键路径。
    最大长度路径即加工工序中最耗时的部分,关键路径也就是求加工工序正常完成的最短时间。
    ~~~~~~       看的视频:浙江大学-数据结构P100
    ~~~~~~       可以看视频进行理解。

数据结构-图内容总结相关推荐

  1. 数据结构--图(Graph)详解(二)

    数据结构–图(Graph)详解(二) 文章目录 数据结构--图(Graph)详解(二) 一.图的存储结构 1.图的顺序存储法 2.图的邻接表存储法 3.图的十字链表存储法 4.图的邻接多重表存储法 二 ...

  2. 四色着色问题 c语言编程,数据结构-图着色问题

    7-38 图着色问题 (25 分) 图着色问题是一个著名的NP完全问题.给定无向图G=(V,E),问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色? 但本题并不是要 ...

  3. 数据结构—图及其应用(交通问题,实现最短路径、最短时间、最少费用查询)

    数据结构-图及其应用(交通问题,实现最短路径.最短时间.最少费用查询) 1.任务描述 (1).任务: 设计一个城市交通咨询模拟系统,利用该系统实现至少两种最优决策:最短路程到达.最省时到达等线路规划. ...

  4. 866数据结构重点内容

    湖大计学考研系列文章目录 22湖南大学计算机学硕上岸经验 22湖南大学 866 数据结构真题(回忆版) 866数据结构重点内容 866 数据结构模拟题(一)及解析 866数据结构笔记 - 第一章 绪论 ...

  5. 数据结构——图——克鲁斯卡尔(Kruskal)算法

    数据结构--图--克鲁斯卡尔(Kruskal)算法 同样的思路,我们也可以直接就以边为目标去构建,因为权值是在边上,直接去找最小权值的边来构建生成树也是很自然的想法,只不过构建时要考虑是否会形成环路而 ...

  6. 数据结构--图(Graph)详解(四)

    数据结构–图(Graph)详解(四) 文章目录 数据结构--图(Graph)详解(四) 一.图中几个NB的算法 1.普里姆算法(Prim算法)求最小生成树 2.克鲁斯卡尔算法(Kruskal算法)求最 ...

  7. 数据结构--图(Graph)详解(三)

    数据结构–图(Graph)详解(三) 文章目录 数据结构--图(Graph)详解(三) 一.深度优先生成树和广度优先生成树 1.铺垫 2.非连通图的生成森林 3.深度优先生成森林 4.广度优先生成森林 ...

  8. 数据结构--图(Graph)详解(一)

    数据结构–图(Graph)详解(一) 文章目录 数据结构--图(Graph)详解(一) 一.图的基本概念 1.图的分类 2.弧头和弧尾 3.入度和出度 4.(V1,V2) 和 < V1,V2 & ...

  9. 【数据结构(C语言)】数据结构-图

    图 文章目录 图 一.基本概念 1.图的定义 2.约定符号 3.分类 4.子图 5.路 6.其他术语 7.ADT 二.存储结构 1.邻接矩阵(数组) 2.邻接表 三.基本算法 1.遍历 2.求无向图的 ...

最新文章

  1. 王树彤IT美女七年磨一剑
  2. 【BZOJ3926】[Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机
  3. 幂函数与指数函数的区别
  4. NVIDIA Tesla/Quadro和GeForce GPU的比较
  5. 创建javascript对象的几种方式
  6. 【国内首家!】阿里云专有云通过商用密码应用安全性评估
  7. 我那个37岁的大神朋友,后续
  8. 李维说他跳槽了,那我以后也不是Borland的Fans了?
  9. scala 冒泡排序
  10. 7-5 BCD解密 (10 分)
  11. 作用JavaScript访问和操作数据库
  12. socket通信问题
  13. C Primer Plus(6) 中文版 第6章 C控制语句:循环 6.2 while语句
  14. 单片机C语言流水灯花样编程,单片机C语言程序设计:花样流水灯
  15. R语言-岭回归的代码与案例解读
  16. 加速度计和陀螺仪指南
  17. 「PS-CC2019新版教程」套索工具-基础篇
  18. 电子元器件贸易如何应用采购管理系统,做好采购订单交期管理?
  19. .NET主流的ORM框架
  20. android输入法框架分析,Android与iOS输入法开发框架比较谈

热门文章

  1. html点击展开盒子变大,JS实现点击按钮控制Div变宽、增高及调整背景色的方法
  2. 夏天水果店怎么打理,如何打理好一个水果店
  3. python文本聚类_python 文本聚类算法
  4. 我是深圳南山的集体户口,要将我老婆的户口随迁入深圳 没有房产,可以办深圳人才中心的集体户口吗
  5. Google PR值
  6. Python之生成器详解
  7. 红米 android8 刷机,小米红米5 plus(安卓8.0)手机刷机图文教程工具分享,快速一键刷机...
  8. 亚马逊后台网页提示HTTP Status 400 – Bad Request无法登陆的解决办法
  9. MSYS2 瘦身小攻略
  10. QQ和360干起来了,中国互联网2大服务商进行白刃战