看数据结构写代码(47)迪杰斯特拉最短路径算法

这个算法的 思想 根 求 最小生成树算法 普里姆(Prim)算法 极其相似。迪杰斯算法 是求 一个顶点 到其他 顶点的 最短路径算法。

下面 上代码:(用的是 邻接矩阵 表示法)

//迪杰斯特拉 最短路径。
//从 vex顶点 到其他 顶点的 最短路径
void shortestPath_Dij(MGraph g,char vex){
	int loc = graphLocation(g,vex);
	int minArray[MAX_VERTEX_NUM]={0};//最小路径值
	bool final[MAX_VERTEX_NUM] = {false};//是否已经完成最小路径
	//初始化vex 到vex 的 数据
	minArray[loc] = 0;
	final[loc] = true;
	int path[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//路径数组,每一行 存放 vex 到这一行的 最短路径
	int pathLenArray[MAX_VERTEX_NUM] = {0};//存放每行路径数组的个数.
	for (int i = 0; i < g.vexNum; i++){
		minArray[i] = g.arcs[loc][i].adj;
		if (minArray[i] < INFINITY){//vex 指向 i
			path[i][0] = i;
			pathLenArray[i] = 1;
		}
	}
	for (int i = 1; i < g.vexNum; i++)//g.verNum -1 个路径
	{
		int min = INFINITY;//最小路径值
		int minIndex = -1;//当前最小路径索引
		int notFind = -1;
		for (int i = 0; i < g.vexNum; i++){//在 minArray 里 寻找 值最小的(不包括已完成的)
			if (final[i] == false){
				if (minArray[i] < min){
					min = minArray[i];
					minIndex = i;
				}
				else
				{
					notFind = i;
				}
			}
			else if(final[i] == false){//没找到.
				notFind = i;
			}
		}
		if(minIndex == -1){//无路径时特殊处理
			minIndex = notFind;
		}
		final[minIndex] = true;//设置 已找到 最小路径
		//打印最小路径,以及 最小路径值
		if (minIndex != notFind){
			printf("%c 到 %c ,最小路径值为:%d,路径为:%c",vex,g.vexs[minIndex],min,vex);
		}
		else{
			printf("%c 到 %c 不可达",vex,g.vexs[minIndex],min,vex);
		}
		int minLen = pathLenArray[minIndex];
		for (int i = 0; i < minLen; i++){
			printf("→ %c",g.vexs[path[minIndex][i]]);
		}
		printf("\n");
		for (int i = 0; i < g.vexNum; i++){//重新 计算 最小路径 数组
			if (final[i] == false){
				int newMin = min + g.arcs[minIndex][i].adj;
				if (newMin < minArray[i]){
					minArray[i] = newMin;
					//重新设置路径
					int j;
					for (j = 0; j < pathLenArray[minIndex]; j++){
						path[i][j] = path[minIndex][j];
					}
					path[i][j] = i;
					pathLenArray[i] = j+1;//设置数组长度.
				}
			}
		}
	}
}

在写 这段代码的时候遇到了两个问题:

1.数值 溢出,书中 用的 INT_MAX ,来表示 顶点之间 不可达的 关系。

当重新计算 最小路径数组的时候 int newMin = min + g.arcs[minIndex][i].adj; 如果 遇到了 INT_MAX,那么代码 逻辑 混乱。

所以 我把 INT_MAX  变成 短整型

#define INFINITY SHRT_MAX

2. 书中的 代码 当 没有 找到 最小值时,然后 访问 final数组 会 堆栈 溢出。加了一个特殊处理。

		if(minIndex == -1){//无路径时特殊处理
			minIndex = notFind;
		}

完整源代码网盘地址:点击打开链接

运行截图:

时间: 2024-10-11 09:41:16

看数据结构写代码(47)迪杰斯特拉最短路径算法的相关文章

43. 蛤蟆的数据结构笔记之四十三最短路径之迪杰斯特拉(Dijkstra )算法

43. 蛤蟆的数据结构笔记之四十三最短路径之迪杰斯特拉(Dijkstra )算法 本篇名言:"辛勤的蜜蜂永没有时间悲哀.--布莱克" 这次来看下Dijkstra )算法.还是老方法,先原理,后实现.代码来自网络. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47046031 1.  最短路径 最短路径问题是图论研究中的一个经典算法问题, 旨在寻找图(由结点和路径组成的)中两结点之间的最短路径. 管道铺设.线路安排

数据结构之---C语言实现最短路径之Dijkstra(迪杰斯特拉)算法

此处共有两段代码: 一. 这段代码比较全面,其中参考了github上的相关源码.可以说功能强大. //Dijkstra(迪杰斯特拉算法) #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 100 // 矩阵最大容量 #define INF 65535 // 最大值65535 #define isLetter(a) ((((a)>='a')&&((a)<

迪杰斯特拉(Dijkstra)算法

1 # include <stdio.h> 2 3 # define MAX_VERTEXES 20//最大顶点数 4 # define INFINITY 65535;//代表∞ 5 6 typedef struct 7 {/* 无向图结构体 */ 8 int vexs[MAX_VERTEXES];//顶点下标 9 int arc[MAX_VERTEXES][MAX_VERTEXES];//矩阵 10 int numVertexes, numEdges;//顶点数和边数 11 12 }MGra

C# 迪杰斯特拉(Dijkstra)算法

Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合.一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知. 初始时,S中仅含有源.设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度.Dijkstra算法每次从V-S中取出具有最短特殊路长度

看数据结构写代码(42)最小生成树

首先给出 一些 概念问题: 1.生成树: 一个n个顶点的 连通图 的 极小连通子图. 它含有n个顶点,但只有 n-1条边,不存在回路. 2.最小生成树:一个带权的 无向连通图,求出 各边权值相加  最小的 生成树,叫做最小生成树. 所以 求最小生成树  首先 要满足: 1. 首先 是 无向图 2. 必须是 连通图(任意两个顶点可达)3.带权 简单的说 就是 必须是 连通网. 求 最小生成树,严蔚敏的 数据结构 给出了 两种 方法:普里姆算法和 克鲁斯卡尔算法. 普里姆算法: 克鲁斯卡尔算法: 克

看数据结构写代码(32) 赫夫曼树编码以及译码

杂谈:最近有点慵懒,不好不好.好几天都没写代码,原本准备上星期完结 树 这一章节的.现在 又耽误了.哎.要抓紧时间啊. 下面直接上代码: 可以到我的网盘下载源代码,或者 直接拷贝下面的源代码 运行 网盘地址:点击打开链接 // HuffmanTree.cpp : 定义控制台应用程序的入口点. //哈弗曼编码,译码 #include "stdafx.h" #include <stdlib.h> #include <cstring> enum E_State { E

看数据结构写代码(44) 判断无向图是否有环路

在 看 严蔚敏的 数据结构 一书 7.5小节时,书上 说" 判断有向图是否存在环要不无向图复杂.对于无向图来说,深度优先遍历过程中遇到回边(即指向已访问过的顶点的边),则必定存在环路". 看的不明白,所以 网上 百度了一下. 有了思路:故写下算法 和思路,以便以后 温故. 思路: 1.一个n个顶点,e条边的 无向图,若 e>= n,必有环路. 2.若 e < n ,需要 深度 遍历,并把 父节点传入 参数中,如果 遇到 一个 节点 被访问过 并且 不是 父节点,那么 就有环

看数据结构写代码(67) 置换 _ 选择排序(完结篇)

杂谈: 严蔚敏版<数据结构(C语言版)> 一书 终于看完了.这是 一个完结,也是 一个新的开端.<算法导论> 已到手. 置换选择排序的思想 是 将 归并段 尽量 变的 更大,而不是根据 内存 大小 限制在 固定的 大小. 这样 可以 利用赫夫曼树 来 进行 最优归并树,从而 使 外存 读写次数 最少. 下面给出 具体 代码:欢迎指出代码不足. // Replace_Selcetion.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h&q

看数据结构写代码(50)伙伴系统

伙伴系统 是一种 只 可以 分配 2的 幂次方 个 空间的 ,回收 内存 时 只 合并 "伙伴空间" 的一种 动态内存管理方式. 例如 一个 空间 大小 为 64 的 内存,伙伴 系统 为 这 64 的内存  建立 一组 双向循环 链表,分别 管理着  2的 0 次方,2的1 次方幂,2的 2 次方幂...2的6次方幂的 可用空间. 即使 我们 只想分配 一个 大小 为3的 空间,系统 却 只能 返回 一个 内存 大小 为 4(2的2次方)的 一个空间. 系统 在 初始化的 时候 ,并