数据结构与算法之图的应用

图的定义和基本概念

  • 在图中,通常将数据元素称为顶点(Vertex) ,数据元素之间的关系称为(Edge) 。
  • (Graph)由有限顶点集V表示顶点之间关系的有限边集E组成,记为: G = ( V , E ) G= (V,E) G=(V,E)
  • 其中:顶点总数|V|记为n,边的总数|E|记为e
  • 无向图:每条边都是无方向的
    在这里插入图片描述
  • 有向图:每条边都是有方向的
    在这里插入图片描述
  • 完全图:任意两个点都有一条边相连
    在这里插入图片描述
  • 顶点的度:与该顶点相关联的边的数目,记为TD(v)
  • 在有向图中, 顶点的度等于该顶点的入度与出度之和。
    顶点 v 的入度是以 v 为终点的有向边的条数, 记作 ID(v)
    顶点 v 的出度是以 v 为始点的有向边的条数, 记作OD(v)
  • 路径:接续的边构成的顶点序列。
  • 路径长度:路径上边或弧的数目/权值之和。
  • 回路(环):第一个顶点和最后一个顶点相同的路径。
  • 简单路径:除路径起点和终点可以相同外,其余顶点均不相同的路径。
  • 简单回路(简单环):除路径起点和终点相同外,其余顶点均不相同的路径。
    在这里插入图片描述
  • 连通图(强连通图)
    在无(有)向图G=( V, {E} )中,若对任何两个顶点 v、u 都存在从v 到 u 的路径,则称G是连通图(强连通图)。
    在这里插入图片描述
  • 权与网
    图中边或弧所具有的相关数称为
    表明从一个顶点到另一个顶点的距离或耗费。带权的图称为
  • 子图。如下图:( b )、( c ) 是 ( a ) 的子图。
    在这里插入图片描述

图的实现

数组〈邻接矩阵〉

  • 无向图的邻接矩阵表示法
    在这里插入图片描述
  • 有向图的邻接矩阵表示法
    在这里插入图片描述
  • 网(即有权图)的邻接矩阵表示法
    在这里插入图片描述
  • 优点:
    容易实现图的操作,如:求某顶点的度、判断顶点之间是否有边、找顶点的邻接点等等。
  • 缺点:
    n个顶点需要n*n个单元存储边;空间效率为 O ( n 2 ) O(n^2) O(n2)。 对稀疏图而言尤其浪费空间。
//用两个数组分别存储顶点表和邻接矩阵
#define MaxInt 32767                    	//表示极大值,即∞
#define MVNum 100                       	//最大顶点数 
typedef char VerTexType;              	//假设顶点的数据类型为字符型 
typedef int ArcType;                  	//假设边的权值类型为整型 
typedef struct{ 
  VerTexType vexs[MVNum];            		//顶点表 
  ArcType arcs[MVNum][MVNum];      	//邻接矩阵 
  int vexnum,arcnum;                		//图的当前点数和边数 
}AMGraph; 

邻接表

  • 无向图的邻接表表示
    在这里插入图片描述
    注:邻接表不唯一,因各个边结点的链入顺序是任意的
    空间效率为O(n+2e)。
    若是稀疏图 ( e < < n 2 ) (e<<n^2) (e<<n2),比邻接矩阵表示法 O ( n 2 ) O(n^2) O(n2)省空间。
  • 有向图的邻接表表示
    在这里插入图片描述
    注:空间效率为O(n+e)
    出度:OD(Vi)=单链出边表中链接的结点数
    入度:ID(Vi)=邻接点域为Vi的弧个数
    度:TD(Vi) = OD(Vi) + I D(Vi)
  • 优点:
    空间效率高,容易寻找顶点的邻接点;
  • 缺点:
    判断两顶点间是否有边或弧,需搜索两结点对应的单链表,没有邻接矩阵方便。
#define MVNum 100                        	//最大顶点数 
typedef struct ArcNode{                		//边结点 
    int adjvex;                          		//该边所指向的顶点的位置 
    struct ArcNode * nextarc;          	//指向下一条边的指针 
    OtherInfo info;                      	              //和边相关的信息 
}ArcNode; 
typedef struct VNode{ 
    VerTexType data;                    	//顶点信息 
    ArcNode * firstarc;                	//指向第一条依附该顶点的边的指针 
}VNode, AdjList[MVNum];               	//AdjList表示邻接表类型 
typedef struct{ 
    AdjList vertices;                 		//邻接表 
    int vexnum, arcnum;              		//图的当前顶点数和边数 
}ALGraph; 

图的应用

最小生成树

Prim(普里姆)算法

图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小。该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克发现;并在1957年由美国计算机科学家罗伯特·普里姆独立发现;1959年,艾兹格·迪科斯彻再次发现了该算法。因此,在某些场合,普里姆算法又被称为DJP算法、亚尔尼克算法或普里姆-亚尔尼克算法。
在这里插入图片描述

Kruskal(克鲁斯卡尔)算法

克鲁斯卡尔算法是求连通网的最小生成树的另一种方法。与普里姆算法不同,它的时间复杂度为 O ( e l o g 2 e ) O(elog_2e) O(elog2e)(e为网中的边数),所以,适合于求边稀疏的网的最小生成树。
在这里插入图片描述

最短路径

  • 最短路径问题是图论研究中的一个经典算法问题, 旨在寻找图(由结点和路径组成的)中两结点之间的最短路径。 算法具体的形式包括:
    • 确定起点的最短路径问题 - 即已知起始结点,求最短路径的问题。
    • 确定终点的最短路径问题 - 与确定起点的问题相反,该问题是已知终结结点,求最短路径的问题。在无向图中该问题与确定起点的问题完全等同,在有向图中该问题等同于把所有路径方向反转的确定起点的问题。
    • 确定起点终点的最短路径问题 - 即已知起点和终点,求两结点之间的最短路径。
    • 全局最短路径问题 - 求图中所有的最短路径。
迪克斯特拉算法
  • 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。
  • 基本思想:
    1.初始化:先找出从源点v0到各终点vk的直达路径(v0,vk),即通过一条弧到达的路径。
    2.选择:从这些路径中找出一条长度最短的路径(v0,u)。
    3.更新:然后对其余各条路径进行适当调整:
    若在图中存在弧(u,vk),且(v0,u)+(u,vk)<(v0,vk),则以路径(v0,u,vk)代替(v0,vk)。
    在调整后的各条路径中,再找长度最短的路径,依此类推。
  • 例如,
    在这里插入图片描述
    在这里插入图片描述
    最短路径为{v0 ,v2 ,v4 ,v3 ,v5}

拓扑排序

对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序

执行步骤

由AOV网构造拓扑序列的拓扑排序算法主要是循环执行以下两步,直到不存在入度为0的顶点为止。

  • (1) 选择一个入度为0的顶点并输出之;
  • (2) 从网中删除此顶点及所有出边。

循环结束后,若输出的顶点数小于网中的顶点数,则输出“有回路”信息,否则输出的顶点序列就是一种拓扑序列。

例如,
在这里插入图片描述
在这里插入图片描述最后得到拓扑序列C4 , C0 , C3 , C2 , C1 , C5

关键路径

  • 关键路径是指设计中从输入到输出经过的延时最长的逻辑路径。优化关键路径是一种提高设计工作速度的有效方法。一般地,从输入到输出的延时取决于信号所经过的延时最大路径,而与其他延时小的路径无关。在优化设计过程中关键路径法可以反复使用,直到不可能减少关键路径延时为止。
  • AOE-网(Activity On Edge)即边表示活动的网。AOE-网是一个带权的有向无环图,其中,顶点表示事件(Event),弧表示活动,权表示活动持续的时间。通常,AOE-网可用来估算工程的完成时间。
  • 一个AOE网,如下图,
    在这里插入图片描述
  • 源点:表示整个工程的开始点,也称起点。
  • 收点:表示整个工程的结束点,也称汇点。
  • 事件结点:单位时间,表示的是时刻。
  • 活动(有向边):它的权值定义为活动进行所需要的时间。
    方向表示起始结点事件先发生,而终止结点事件才能发生。
  • 关键活动:最早开始时间 = 最迟开始时间的活动
  • 关键路径:从源点到收点的最长的一条路径,或者全部由关键活动构成的路径。
  • 四个主要描述量
    在这里插入图片描述
    在这里插入图片描述
    例如,已知AOE网中顶点v1,v2,v3,…v7分别表示7个时间,有向线段a1,a2,a3,…a10分别表示10个活动,线段旁的数值表示每个活动花费的天数,如下图所示。用顶点序列表示出关键路径,给出关键活动。
    在这里插入图片描述
    解析:
    在这里插入图片描述
    故关键路径:
    (1)V1->V2->V5->V7
    (2)V1->V4->V5->V7
    注意:关键路径可有多条缩短工期必须缩短关键活动所需的时间

参考文献

[1] 严蔚敏,吴伟民. 数据结构(C语言版). 北京: 清华大学出版社,2020
[2] 严蔚敏,李冬梅,吴伟民. 数据结构(C语言版)(第二版). 北京: 人民邮电出版社,2021
[3] 吴伟民,李小妹,刘添添,黄剑锋,苏庆,林志毅,李杨.数据结构. 北京:高等教育出版社,2017

  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FriendshipT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值