最短路径:Dijkstra算法(求单源最短路径)Floyd算法(求各顶点之间最短路径)[通俗易懂]

最短路径:Dijkstra算法(求单源最短路径)Floyd算法(求各顶点之间最短路径)[通俗易懂]最短路径:在一个带权图中,顶点V0到图中任意一个顶点Vi的一条路径所经过边上的权值之和,定义为该路径的带权路径长度,把带权路径最短的那条路径称为最短路径。DiskStra算法:求单源最短路径,即求一个顶点到任意顶点的最短路径,其时间复杂度为O(V*V)如图所示:求顶点0到各顶点之间的最短路径代码实现:#include<stdio.h>#include&l…

大家好,又见面了,我是你们的朋友全栈君。

最短路径:

在一个带权图中,顶点V0到图中任意一个顶点Vi的一条路径所经过边上的权值之和,定义为该路径的带权路径长度,把带权路径最短的那条路径称为最短路径。

DiskStra算法:

求单源最短路径,即求一个顶点到任意顶点的最短路径,其时间复杂度为O(V*V)

最短路径:Dijkstra算法(求单源最短路径)Floyd算法(求各顶点之间最短路径)[通俗易懂]

如图所示:求顶点0到各顶点之间的最短路径

代码实现:

#include<stdio.h>
#include<stdlib.h>
#define MaxVexNum 50
#define MaxInt 32767
#define MaxEdgeNum 50
//邻接矩阵
typedef int VertexType;
typedef int EdgeType;
typedef struct AMGraph{
	VertexType vexs[MaxVexNum];//顶点表 
	EdgeType arcs[MaxVexNum][MaxVexNum];//邻接矩阵表 
	int vexnum,edgenum;//顶点数,边数 
}AMGraph; 

void createGraph(AMGraph &g){//创建无向图 
	printf("请输入顶点数:");
	scanf("%d",&g.vexnum);
	printf("\n请输入边数:");
	scanf("%d",&g.edgenum);
	
	//初始化顶点表 
	for(int i=0;i<g.vexnum;i++){
		g.vexs[i]=i; 
	} 
	for(int i=0;i<g.vexnum;i++){
		for(int j=0;j<g.vexnum;j++){
			g.arcs[i][j]=MaxInt;
			if(i==j) g.arcs[i][j]=0;
		}
	} 
	printf("请输入边的信息以及边的权值(顶点是0~n-1)\n");
	for(int i=0;i<g.edgenum;i++){
		int x,y,w;
		scanf("%d%d%d",&x,&y,&w);
		g.arcs[x][y]=w;
		//g.arcs[y][x]=w;
	}
}
void PrintGraph(AMGraph g){
	printf("邻接矩阵为:\n");
	for(int i=0;i<g.vexnum;i++) {
		printf("  %d",g.vexs[i]);
	}
	printf("\n");
	for(int i=0;i<g.vexnum;i++){
		printf("%d ",g.vexs[i]);
		for(int j=0;j<g.vexnum;j++){
			if(g.arcs[i][j]==32767){
				printf("∞ "); 
			}else{
				printf("%d  ",g.arcs[i][j]);
			}	
		}
		printf("\n");
	} 
}
//Dijkstra算法,求单源最短路径
void Dijkstra(AMGraph g,int dist[],int path[],int v0){
	int n=g.vexnum,v;
	int set[n];//set数组用于记录该顶点是否归并 
	//第一步:初始化 
	for(int i=0;i<n;i++){
		set[i]=0;
		dist[i]=g.arcs[v0][i];
		if(dist[i]<MaxInt){//若距离小于MaxInt说明两点之间有路可通 
			path[i]=v0;//则更新路径i的前驱为v 
		}else{
			path[i]=-1; //表示这两点之间没有边
		 } 
	}
	set[v0]=1;//将初始顶点并入 
	path[v0]=-1;//初始顶点没有前驱
	
	//第二步 
	for(int i=1;i<n;i++){//共n-1个顶点 
		int min=MaxInt;
		//第二步:从i=1开始依次选一个距离顶点的最近顶点 
		for(int j=0;j<n;j++){
			if(set[j]==0&&dist[j]<min){
				v=j;
				min=dist[j];
		}
	}
	//将顶点并入 
	set[v]=1;	
	//第三步:在将新结点并入后,其初始顶点v0到各顶点的距离将会发生变化,所以需要更新dist[]数组
	for(int j=0;j<n;j++){
		if(set[j]==0&&dist[v]+g.arcs[v][j]<dist[j]){
			dist[j]=dist[v]+g.arcs[v][j];
			path[j]=v;
		}
	} 	
 } 
 //输出 
 printf("       ");
 for(int i=0;i<n;i++) printf("%d  ",i);
  
 printf("\ndist[]:");
 for(int i=0;i<n;i++) printf("%d  ",dist[i]);
 
 printf("\npath[]:");
 for(int i=0;i<n;i++) printf("%d  ",path[i]);

}

int main(){
	AMGraph g;
	createGraph(g);
	int dist[g.vexnum];
	int path[g.vexnum];
	Dijkstra(g,dist,path,0);
} 

最短路径:Dijkstra算法(求单源最短路径)Floyd算法(求各顶点之间最短路径)[通俗易懂]

Floyd算法:

求各顶点之间的最短路径,其时间复杂度为O(V*V*V)

最短路径:Dijkstra算法(求单源最短路径)Floyd算法(求各顶点之间最短路径)[通俗易懂]

如图所示,求<1,0>之间的最短路径:

代码实现:

#include<stdio.h>
#include<stdlib.h>
#define MaxVexNum 50
#define MaxInt 32767
#define MaxEdgeNum 50
//邻接矩阵
typedef int VertexType;
typedef int EdgeType;
typedef struct AMGraph{
	VertexType vexs[MaxVexNum];//顶点表 
	EdgeType arcs[MaxVexNum][MaxVexNum];//邻接矩阵表 
	int vexnum,edgenum;//顶点数,边数 
}AMGraph; 

void createGraph(AMGraph &g){//创建无向图 
	printf("请输入顶点数:");
	scanf("%d",&g.vexnum);
	printf("\n请输入边数:");
	scanf("%d",&g.edgenum);
	
	//初始化顶点表 
	for(int i=0;i<g.vexnum;i++){
		g.vexs[i]=i; 
	} 
	for(int i=0;i<g.vexnum;i++){
		for(int j=0;j<g.vexnum;j++){
			g.arcs[i][j]=MaxInt;
			if(i==j) g.arcs[i][j]=0;
		}
	} 
	printf("请输入边的信息以及边的权值(顶点是0~n-1)\n");
	for(int i=0;i<g.edgenum;i++){
		int x,y,w;
		scanf("%d%d%d",&x,&y,&w);
		g.arcs[x][y]=w;
		//g.arcs[y][x]=w;
	}
}
void PrintGraph(AMGraph g){
	printf("邻接矩阵为:\n");
	for(int i=0;i<g.vexnum;i++) {
		printf("  %d",g.vexs[i]);
	}
	printf("\n");
	for(int i=0;i<g.vexnum;i++){
		printf("%d ",g.vexs[i]);
		for(int j=0;j<g.vexnum;j++){
			if(g.arcs[i][j]==32767){
				printf("∞ "); 
			}else{
				printf("%d  ",g.arcs[i][j]);
			}	
		}
		printf("\n");
	} 
}

//Floyd算法

//递归输出两个顶点直接最短路径 
void printPath(int u,int v,int path[][MaxVexNum]){
	if(path[u][v]==-1){
		printf("[%d %d] ",u,v);
	}else{
		int mid=path[u][v];
		printPath(u,mid,path);
		printPath(mid,v,path);
	}
}
void Floyd(AMGraph g,int path[][MaxVexNum]){
	int n=g.vexnum;
	int A[n][n];
	//第一步:初始化path[][]和A[][]数组 
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			A[i][j]=g.arcs[i][j];
			path[i][j]=-1; 
		}
	}
	//第二步:三重循环,寻找最短路径 
	for(int v=0;v<n;v++){//第一层是代表中间结点 
		for(int i=0;i<n;i++){
			for(int j=0;j<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;
				}
			}
		} 
	} 
} 
 
int main(){
	AMGraph g;
	createGraph(g);
	PrintGraph(g);
	int path[MaxVexNum][MaxVexNum];
	Floyd(g,path);

	printPath(1,0,path);
} 

代码运行截图:

最短路径:Dijkstra算法(求单源最短路径)Floyd算法(求各顶点之间最短路径)[通俗易懂]

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/152181.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • goland2021.2激活破解码

    idea激活码:https://javaforall.net/100143.html,全栈程序员必看教程网idea激活码推荐

    2022年3月14日
    246
  • SSM框架下,访问不到静态资源

    SSM框架下,访问不到静态资源记一次小问题。 做项目时,启动Tomcat,发现.jsp文件都能访问,但是同路径下的Html不能访问。服务器什么一切正常,没有任何错误信息。但就是最后返回视图的时候总是找不到资源。 经过仔细查找,发现原来在springmvc中,如果配置/拦截所有的请求,,那么在返回视图的.html url中一样会被拦截。但此时dispatcheservlet 拦截…

    2022年6月13日
    33
  • p2p网络传输协议

    p2p网络传输协议P2P是英文Peer-to-Peer(对等)的简称,又被称为“点对点”。“对等”技术,是一种网络新技术,依赖网络中参与者的计算能力和带宽,而不是把依赖都聚集在较少的几台服务器上。P2P还是英文PointtoPoint(点对点)的简称。它是下载术语,意思是在你自己下载的同时,自己的电脑还要继续做主机上传,这种下载方式,人越多速度越快但缺点是对硬盘损伤比较大(在写的同时还要读),还有对内存占用较…

    2022年7月16日
    28
  • 一键端2

    一键端2一键端

    2022年7月19日
    37
  • java 正则表达式语法_JAVA正则表达式语法大全

    java 正则表达式语法_JAVA正则表达式语法大全元字符描述\将下一个字符标记符、或一个向后引用、或一个八进制转义符。例如,“\\n”匹配\n。“\n”匹配换行符。序列“\\”匹配“\”而“\(”则匹配“(”。即相当于多种编程语言中都有的“转义字符”的概念。^匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。$匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline…

    2022年7月19日
    16
  • html下划线[通俗易懂]

    html下划线[通俗易懂]<spanstyle=”text-decoration:underline;”> 划重点</span>

    2022年6月4日
    26

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号