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 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 图的最短路径——迪杰斯特拉算法(Dijkstra算法)、弗洛伊德算法(Floyd算法)和广度优先搜索(BFS)算法求最短路径(无权图) -> 正文阅读

[数据结构与算法]图的最短路径——迪杰斯特拉算法(Dijkstra算法)、弗洛伊德算法(Floyd算法)和广度优先搜索(BFS)算法求最短路径(无权图)

一、迪杰斯特拉算法(Dijkstra算法)

(1)算法

从某一顶点到其余各项顶点的最短路径。

引进三个辅助数组dist[]、path[]和set[]。

dist[vi]表示当前已找到的从v0到vi的最短路径长度。

path[vi]中保存从v0到vi最短路径上vi的前一个顶点。

set[]为标记数组。

/*邻接矩阵的结构定义*/
#define maxSize 100
typedef struct{
	int edges[maxSize][maxSize]; //邻接矩阵定义
	int n, e; //分别为顶点数和边数
}MGraph;

/*最短路径,迪杰斯特拉算法(Dijkstra算法),从某一顶点到其余各项顶点的最短路径*/
void Dijkstra(MGraph g, int v0, int dist[], int path[]){
	int set[maxSize]; //标记数组
	int i, j, min, v;
	/*对各数组进行初始化*/
	for(i=0;i<g.n;i++){
		dist[i]=g.edges[v0][i];
		set[i]=0;
		if(g.edges[v0][i]<INF)
			path[i]=v0;
		else
			path[i]=-1;
	}
	set[v0]=1;
	path[v0]=-1;
	/*初始化结束*/
	/*关键操作开始*/
	for(i=0;i<g.n-1;i++){
		min=INF;
		/*这个循环每次从剩余顶点中选出一个顶点,通往这个顶点的路径在通往所有剩余顶点的路径中是长度最短的*/
		for(j=0;j<g.n;j++){
			if(set[j]==0&&dist[j]<min){
				v=j;
				min=dist[j];
			}
		}
		set[v]=1; //将选出的顶点并入最短路径中
		/*这个循环以刚并入的顶点作为中间点,对所有通往剩余顶点的路径进行检测*/
		for(j=0;j<g.n;j++){
			/*这个if语句判断顶点v的加入是否会出现通往顶点j的更短的路径,如果出现,则改变原来路径及其长度,否则什么都不做*/
			if(set[j]==0&&dist[v]+g.edges[v][j]<dist[j]){
				dist[j]=dist[v]+g.edges[v][j];
				path[j]=v;
			}
		}
	}
}
/*函数结束时,dist[]数组中存放了v点到其余顶点的最短路径长度,path[]中存放v点到其余各顶点的最短路径*/

(2)时间复杂度

迪杰斯特拉算法的时间复杂度为O(n2)。

(3)path[]数组打印最短路径经过的所有顶点

path[]数组中其实保存了一棵树,这是一棵用双亲存储结构存储的树,通过这棵树可以打印出从源点到任何一个顶点最短路径上所经过的所有顶点。
树的双亲表示法只能输出由叶子结点到根结点的路径,而不能逆向输出,因此需要借助一个栈来实现逆向输出。

void printfPath(int path[], int a){
	int stack[maxSize];
	int top=-1;
	/*此循环以由叶子结点到根结点的顺序将其入栈*/
	while(path[a]!=-1){
		stack[++top]=path[a];
		a=path[a];
	}
	stack[++top]=a;
	while(top!=-1){
		cout<<stack[top--]<<" "; //出栈并打印出栈元素,实现了顶点的逆序打印
	cout<<endl;
	}
}

二、弗洛伊德算法(Floyd算法)

(1)算法

求图中任意一对顶点间的最短路径。

void Floyd(MGraph g, int path[][maxSize]){
	int i, j, v;
	int A[maxSize][maxSize];
	/*下面这个双循环对数组A[][]和path[][]进行了初始化*/
	for(i=0;i<g->n;i++)
		for(j=0;j<g->n;j++){
			A[i][j]=g->edges[i][j];
			path[i][j]=-1;
		}
	/*以下三层循环完成了以k为中间点,对所有顶点对(i,j)进行检测和修改*/
	for(v=0;v<g->n;v++)
		for(i=0;i<g->n;i++)
			for(j=0;j<g->n;j++){
				if(A[i][j]>A[i][v]+A[v][j]){
					A[i][j]=A[i][v]+A[v][j];
					path[i][j]=v;
				}
			}
}

(2)时间复杂度

佛洛依德算法的时间复杂度为O(n^3)。

(3)输出u、v两个顶点之间的最短路径的顶点序列

/*伪代码*/
void printPath(int u, int v, int path[][maxSize]){
	if(path[u][v]==-1)
		直接输出;
	else{
		int mid=path[u][v];
		printPath(u,min,path);
		printPath(min,v,path);
	}
}

三、广度优先搜索(BFS)算法(无权图)

(1)算法

/*图的邻接矩阵存储结构定义*/
#define MaxVertexNum 100 //顶点数目的最大值
typedef char VertexType; //顶点数据类型
typedef int EdgeType; //带权图中边上权值的数据类型
typedef struct{
	VertexType Vex[MaxVertexNum]; //顶点表
	EdgeType Edge[MaxVertexNum][MaxVertexNum]; //邻接矩阵,边表
	int vernum, arcnum;
}MGraph;

//求顶点u到其他顶点的最短路径
void BFS_MIN_Distance(MGraph G, int u){
	//d[i]表示从u到i结点的最短路径
	for(int i=0;i<G.vernum;i++){
		d[i]=∞; //初始化路径长度
		path[i]=-1; //最短路径从哪个顶点过来
		visited[i]=false; //标记数组
	}
	d[u]=0;
	visited[u]=true;
	EnQueue(Q,u);
	while(!IsEmpty(Q)){ //BFS算法主过程
		DeQueue(Q,u); //队头元素u出队
		for(w=FirstNeighbor(G,u);w>=0;w=NextNeighbor(G,u,w)){
			if(!visited[w]){ //w为u的尚未访问过的邻接顶点
				d[w]=d[u]+1; //路径长度加1
				path[w]=u; //最短路径应从u到w
				visited[w]=true; //设已访问标记
				EnQueue(Q,w); //顶点w入队
			}
		}
	}

}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-26 12:18:24  更:2021-07-26 12:20:43 
 
开发: 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年12日历 -2024/12/27 9:53:10-

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