IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构-图的应用-最短路径(类C语言版) -> 正文阅读

[数据结构与算法]数据结构-图的应用-最短路径(类C语言版)

最短路径问题

典型用途

交通网络的问题——从甲地到乙地之间是否有公路连通?在有多条通路的情况下,哪一条路最短?
在这里插入图片描述
交通网络用有向图来表示:
顶点——表示地点,
弧——表示两个地点有路连通,
弧上的权值——表示两地点之间的距离、交通费或图中所花费的时间等。

如何能够使一个地点到另一个地点的运输时间最短或运费最省?这就是一个求两个地点间的最短路径的问题。

问题抽象

在有向网中A点(源点)到达B点(终点)的多条路径中,寻找一条各边权值之和最小的路径,即最短路径。

最短路径与最小生成树不同,路径上不一定包含n个顶点,也不一定包含n-1条边。

引出问题

第一类问题:两点间最短路径

用Dijkstra(迪杰斯特拉)算法。
在这里插入图片描述

第二类问题:某源点到其他各点最短路径

用Floyd(弗洛伊德)算法。

在这里插入图片描述

Dijistra算法

(1)初始化:先找出从源点v0到各终点vk的直达路径(v0, vk),即通过一条弧到达的路径。
(2)选择:从这些路径中找出一条长度最短的路径(v0, u)。
(3)更新:然后对其余各条路径进行适当调整:
若在图中存在弧(u, vk),且(v0, u) + (u, vk) < (v0, vk),则以路径(v0, u, vk)代替(v0, vk)。
在调整后的各条路径中,再找长度最短的路径,以此类推。

void ShortestPath_DIJ(AMGraph G, int v0) 
{	// 用Dijkstra算法求有向网G的vO顶点到其余顶点的最短路径
	n=G.vexnum; 					// n为G 中顶点的个数
	for(v= O;v<n; ++v) 				// n个顶点依次初始化
	{
		S[v]=false;					// S初始为空集
		D[v]=G.arcs[v0][v];			// 将v0到各个终点的最短路径长度初始化为弧上的权值
		if(D[v]<Maxlnt) Path[v]=vO; // 如果v0和v之间有弧, 则将v的前驱置为v0
		else Path[v]=-1;			// 如果v0 和v之间无弧, 则将v的前驱置为-1
	}
	S[v0] = true; 					// 将v0加人 S
	D[v0]=0;						// 源点到源点的距离为 0
/*--------初始化结束, 开始主循环, 每次求得vO到某个顶点v的最短路径, 将v加到s集----*/
	for(i=1;i<n;++i)				// 对其余 n-1个顶点,依次进行计算
	{
		min=MaxInt;
		for(w= O;w<n;++w) 
			if(!S[w]&&D[w]<min)
				{v=w;min=D[w];}		// 选择一条当前的最短路径,终点为v
		S[v]=true;					// 将v加入S
		for(w=0;w<n;++w)			// 更新从v0出发到集合V-S上所有顶点的最短路径长度
			if(!S[w]&&(D[v]+G.arcs[v][w]<D[w]))
			{
				D[w]=D[v]+G.arcs[v][w];	// 更新D[w]
				Path[w]=v;			// 更改w的前驱为v
			}
	}
}

迪杰斯特拉(Dijkstra)算法描述

按路径长度递增次序产生最短路径
1.把V分成两组:
(1)S:已求出最短路径的顶点的集合。
(2)T=V-S:尚未确定最短路径的顶点集合。
2.将T中顶点按最短路径递增的次序加入到S中,保证:
(1)从源点v0到S中各顶点的最短路径长度都不大于从v0到T中任何顶点的最短路径长度。
(2)每个顶点对应一个距离值:
S中顶点:从v0到此顶点的最短路径长度。
T中顶点:从v0到此顶点的只包括S中顶点作中间顶点的最短路径长度。

算法步骤

初始时令S={v0},T={其余顶点}。
在这里插入图片描述

实例

在这里插入图片描述

弗洛伊德(Floyd)算法

初始时设置一个n阶方阵,令其对角线元素为0,若存在弧<vi, vj>,则对应元素为权值;否则为∞。
逐步试着在原直接路径中增加中间顶点,若加入中间顶点后路径变短,则修改之;否则,维持原值。所有顶点试探完毕,算法结束。

void ShortestPath_Floyd(AMGraph G)
{	//用Floyd算法求有向网G中各对顶点i和j之间的最短路径
	for (i=O; i < G.vexnum; ++i) 				// 各对结点之间初始已知路径及距离
		for(j=O;j <G.vexnum;++j) 
		{
			D[i][j] =G.arcs [i][j];
			if(D[i][j]<Maxint) Path[i][j]=i; 	//如果 i和j 之间有弧,则将j的前驱置为i.
			else Path[i][j]=-1;					// 如果 i和j 之间无弧,则将j的前驱置为-1
		}
	for (k=O; k < G.vexnum; ++k) 
		for (i=O; i <G.vexnum;++i) 
			for(j=O;j <G.vexnum;++j) 
				if(D[i][k]+D[k][j] <D[i][j]) 	// 从i经k到j的一条路径更短
				{
					D[i][j]=D[i][k]+D[k][j]; 	// 更新D[i][j]
					Path[i][j]=Path[k][j];		// 更改j的前驱为k
				}
}

算法思想

  • 逐个顶点试探;
  • 从vi到vj的所有可能存在的路径中;
  • 选出一条长度最短的路径。

实例

在这里插入图片描述

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-06-08 19:12:49  更:2022-06-08 19:13:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:52:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码