迪杰斯特拉算法

/**
*2018.9.28 22:53
*迪杰斯特拉算法
*求源点到其余所有点的最短路径
*核心思想:cost数组表示源点到该点的距离(权重之和),path表示源点到该点的中间顶点
*set表示该点是否是否已经找到最短路径
*1.初始化cost数组(源点到各点的直接距离,路径存在则path[i] = source)
	set每个元素初始化为0
*2.将源点的path设置为-1,表示没有路径,并set[source] = 1,表示已在最短路径中
*3.找出没有在最短路径中且到源点到该顶点路径最短的顶点(该点)
*4.将该点并入最短路径中set[该点] = 1
*5.从该点出发,从该点到在未并入最短路径的每个顶点
*6.比较从源点到该点的路径长度(cost[该点])+
	该点到某个未并入最短路径的顶点的路径长度(edge[该点][某个未并入顶点])
	与 源点到某个未并入最短路径的顶点的路径长度(cost[某个未并入顶点])
*7.若前者小于后者,则更新 cost[某个未并入顶点] = cost[该点] + edge[该点][某个未并入顶点]
* 且更新  path[某个未并入顶点] = 该点
*
*tips:最后的path数组其实存储了一棵树(双亲表示法)
*	   path中其实是保存的是顶点i到源点的路径间的上一个顶点
*/
#include<stdio.h>

#define MAX 100
//表示两点之间没有路径
#define MAX_WEIGHT 1000

typedef struct Matrix {
	char e[MAX];
	int edge[MAX][MAX];
	int v_num, e_num;
}Matrix;

void Dijkstra(Matrix g, int cost[], int path[], int source);
void printPath(int path[], int terminus);


int main(void) {
	Matrix g = {
	"hhhaah",
	{{MAX_WEIGHT, 4,6,6,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT},
	 {MAX_WEIGHT,MAX_WEIGHT,1,MAX_WEIGHT,7,MAX_WEIGHT,MAX_WEIGHT},
	 {MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,6,4,MAX_WEIGHT},
	 {MAX_WEIGHT,MAX_WEIGHT,2,MAX_WEIGHT,MAX_WEIGHT,5,MAX_WEIGHT},
	 {MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,6},
	 {MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,1,MAX_WEIGHT,8},
	 {MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT},
	},
	7,7 
	};
	int cost[MAX],path[MAX];
	 
	Dijkstra(g, cost, path, 0);

	printPath(path ,5);

	putchar('\n');
	system("pause");
	return 0;
}


void Dijkstra(Matrix g, int cost[], int path[], int source) {
	int i, j, min, set[MAX], k;
	for (i = 0; i < g.v_num; ++i) {
		cost[i] = g.edge[source][i];
		set[i] = 0;
		if (cost[i] != MAX_WEIGHT) 
			path[i] = source;
		else path[i] = -1;
	}
	//看在邻接矩阵是怎么规定某点到自己的距离的
	//是MAX_WEIGHT则直接用下这句,若是用0表示,则加path[source] = -1;
	set[source] = 1;

	for (i = 0; i < g.v_num - 1; ++i) {
		min = MAX_WEIGHT;
		for (j = 0; j < g.v_num; ++j) {
			if (set[j] == 0 && min > cost[j]) {
				min = cost[j];
				k = j;
			}
		}
		set[k] = 1;
		for (j = 0; j < g.v_num; ++j) {
			if (set[j] == 0 && cost[j] > cost[k] + g.edge[k][j]) {
				cost[j] = cost[k] + g.edge[k][j];
				path[j] = k;
			}
		}
	}
}


void printPath(int path[], int terminus) {
	int stack[MAX], i = terminus, top =-1;
	stack[++top] = i;
	
	while (path[i] != -1) {
		stack[++top] = path[i];
		i = path[i];
	}
	
	while ( top != -1) 
		printf("%d ", stack[top--]);
	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值