ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

图—Dijkstra算法求最短路径

2021-12-17 10:35:25  阅读:204  来源: 互联网

标签:算法 dist min int 路径 Dijkstra vex length VN


数据结构

typedef int VexType;
typedef int AdjType;

/*图*/ 
typedef struct{
    VexType vexs[VN];		//结点 
    AdjType arcs[VN][VN];	//权值 
}GraphMatrix; 

/*路径*/ 
typedef struct{
    AdjType length;			 
    VexType prevex;			
}Path;				
Path dist[VN];

1.二维数组 arcs[VN][VN] 储存图的边权数据,一维数组 vexs[VN] 储存图的结点数据;

2.结构体 Path 保存起始点到每个结点的最短距离length,到该点的最短距离的上一个结点prevex

二、核心算法—Dijkstra算法

/*初始化路径矩阵*/
void Init_Path(GraphMatrix *G, Path dist[]){
	dist[0].length = 0;
	dist[0].prevex = 0;
	G->arcs[0][0] = 1;
	for(int i=1; i<VN; ++i){
		dist[i].length = G->arcs[0][i];
		if(dist[i].length != MAX)	dist[i].prevex = 0;
		else 						dist[i].prevex = -1;
	}
}

/*Dijkstra算法寻找最短路径*/
void Dijkstra(GraphMatrix *G ,Path dist[]){
	int i,j,min_vex,min_length;
	
	Init_Path(G,dist);
	
	for(i=1; i<VN; ++i){
		min_length = MAX;	//当前到Vi的最短路径长度 
		min_vex = 0;		//当前到Vi的最短路径对应的上一个结点
		 
		for(j=1; j<VN; ++j){
			if(G->arcs[j][j] == 0 && dist[j].length < min_length){
				min_vex = j;
				min_length = dist[j].length;
			}
		}
		if(min_vex == 0) break;
		G->arcs[min_vex][min_vex] = 1;
		
		for(j=1; j<VN; ++j){
			if(G->arcs[j][j] == 0 && dist[j].length > dist[min_vex].length + G->arcs[min_vex][j]){
				dist[j].prevex = min_vex;
				dist[j].length = dist[min_vex].length + G->arcs[min_vex][j];
			}
		}
	}
}

三、完整代码

#include <stdio.h>
#include <stdlib.h>
#define VN 	6				//邻接矩阵大小(v0 - v5) 
#define MAX 999				//不可到达点的权值(即无穷大)

typedef int VexType;
typedef int AdjType;

/*图*/ 
typedef struct{
    VexType vexs[VN];		//结点 
    AdjType arcs[VN][VN];	//权值 
}GraphMatrix; 

/*路径*/ 
typedef struct{
    AdjType length;			 
    VexType prevex;			 
}Path;				
Path dist[VN];


/*打印图的邻接矩阵*/
void Print_Graph(GraphMatrix *G){
	int i,j;
	printf("G->arcs[][] = \n\t");
	for(i=0; i<VN; ++i) 
		printf(" V%d \t",G->vexs[i]);
		printf("\n");
	
	for(i=0; i<VN; ++i){
		printf(" V%d \t",G->vexs[i]);
  		for(j=0; j<VN; j++)
			printf(" %d \t",G->arcs[i][j]);
		printf("\n");
 	}
 	printf("\n");
}

/*打印图的路径矩阵*/
void Print_Path(Path dist[]){
	printf("dist[] = \n");
	for(int i=0; i<VN; i++)
		printf(" V%d: prevex = %d   lenght = %d\n",i,i,dist[i].length,i,dist[i].prevex);
	printf("\n"); 
}

/*打印两点间的最短路径*/
void Print_Length(int start_vex, int end_vex, Path dist[], GraphMatrix *G){
	if(start_vex > end_vex || end_vex > VN-1 || start_vex < 0) {
		printf("输入错误!");
		return;
	}
	int i = end_vex;
	printf("%d -> ",G->vexs[end_vex]);
	while(dist[i].prevex != start_vex){
		printf("%d -> ",G->vexs[dist[i].prevex]);
		i = dist[i].prevex;
	}
	printf("%d = %d",G->vexs[start_vex],dist[end_vex].length - dist[start_vex].length);
	return;
}

/*寻找结点G->vexs[i]对应的储存位置i*/
int Find(int find_point, GraphMatrix *G){
	for(int i=0; i<VN; i++)
		if(G->vexs[i] == find_point) return i;
	return -1;
}

/*初始化图并输入权值*/
GraphMatrix* Init_Graph(){
	int begin,end,weight,i,j;
    GraphMatrix *G = (GraphMatrix*)malloc(sizeof(GraphMatrix));
    
	/*初始化图的邻接矩阵 arcs[VN][VN] */
	for (i=0; i<VN; i++){ 
		for (j=0; j<VN; j++){
			if(i == j)	G->arcs[i][j] = 0;		//对角线权值为0 
			else		G->arcs[i][j] = MAX;	//除对角线外所有权值为无穷大 
		}
	} 
	
	/*初始化图的结点矩阵 vexs[VN] */ 
	int v[VN] = {1,2,3,4,5,6};
	for(i=0; i<VN; i++)
		G->vexs[i] = v[i];
		
	/*初始化图的边权*/
	int  start_vex[9] = {0,0,1,1,3,3,2,3,4};
	int    end_vex[9] = {1,2,2,3,2,4,4,5,5};
	int vex_weight[9] = {1,12,9,3,4,13,5,15,4};
	for(i=0; i<9; i++)
		G->arcs[start_vex[i]][end_vex[i]] = vex_weight[i];
	return G;
}

/*初始化路径矩阵*/
void Init_Path(GraphMatrix *G, Path dist[]){
	dist[0].length = 0;
	dist[0].prevex = 0;
	G->arcs[0][0] = 1;
	for(int i=1; i<VN; ++i){
		dist[i].length = G->arcs[0][i];
		if(dist[i].length != MAX)	dist[i].prevex = 0;
		else 						dist[i].prevex = -1;
	}
}

/*Dijkstra算法寻找最短路径*/
void Dijkstra(GraphMatrix *G ,Path dist[]){
	int i,j,min_vex,min_length;
	
	Init_Path(G,dist);
	
	for(i=1; i<VN; ++i){
		min_length = MAX;	//当前到Vi的最短路径长度 
		min_vex = 0;		//当前到Vi的最短路径对应的上一个结点
		 
		for(j=1; j<VN; ++j){
			if(G->arcs[j][j] == 0 && dist[j].length < min_length){
				min_vex = j;
				min_length = dist[j].length;
			}
		}
		if(min_vex == 0) break;
		G->arcs[min_vex][min_vex] = 1;
		
		for(j=1; j<VN; ++j){
			if(G->arcs[j][j] == 0 && dist[j].length > dist[min_vex].length + G->arcs[min_vex][j]){
				dist[j].prevex = min_vex;
				dist[j].length = dist[min_vex].length + G->arcs[min_vex][j];
			}
		}
	}
}


int main()
{
	int i,j;
	GraphMatrix *G =Init_Graph();
	
	Print_Graph(G);
	Dijkstra(G,dist);
	Print_Path(dist);
	
	printf("起点:"); scanf("%d",&i);
	printf("终点:"); scanf("%d",&j);
	if(Find(i,G) != -1 && Find(j,G) != -1) 
		Print_Length(Find(i,G),Find(j,G),dist,G);
    return 0;
}

输出结果:

从v1到v6:

从v4到v6: 

标签:算法,dist,min,int,路径,Dijkstra,vex,length,VN
来源: https://blog.csdn.net/sun80760/article/details/121989728

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有