【算法导论】第24章迪杰斯特拉算法
1、问题引入
在带权有向图中求解某个源点到其余各个顶点的最短路径一般可以采用迪杰斯特拉算法(Dijkstra算法)。
2、算法的主体思想:
引用:(http://hi.baidu.com/wangziming/blog/item/d352be19d53e554642a9ad62.html)
A、找到v——Other所有路径中的的最短路径vd=v——d(Other的一个元素);
B、找到v——S——Other所有路径中的的最短路径vi=v——i(Other的一个元素);
C、比较vd和vi如果vd<=vi则将d加入S且从Other中删除,否则将i加入S且从Other中删除。
重复以上步骤直至Other为空集。
3、一个问题:
这里说明一个问题:假设S为已经求的的最短路径的终点的集合,则可以证明:下一条最短路径(设其终点为x)或者是弧(v,x),或者是中间只经过S中的顶点而最后到达顶点x的路径;可以用反证法证明:(引用)我们求得的最短路径是升序排列的,假设x是存在于v——Other(v1)——Other(v2)之中,那么肯定有一条比这条路径更短的路径v——Other(v1)我们没找到,也就是说,我们所找的v2是从已经求的的最短路径开始搜索的,,其前一个节点必然存在于S中,如果不存在于S中,这就算法本身的思路相背离,必然为不正确的。。。我刚开始看这个算法的时候也是纠结在这里,,一直看不明白,,觉得有些不理解,,以为v-other-other中说不定就存在比v-S-other或者v-other更短的路径,,其实这是不可能的,,如果有最短的路径,必然是已经求解出来的。。。。。
4、具体实现过程:
这个算法在许多书上都有介绍,严蔚敏老师的数据结构上就有,,,这里算法实现中和严老师的有一点点的区别,即:使用prev[i]来记录从起始点到点i的最短路径中i点的前一个节点,,这样在最后得出路径的时候直接从i向前直到起始点就可以方便得出了。。。
程序实现中用了一个txt文件,其中第一个值用于记录点的个数,其他数据表示各个点之间的可达关系:比如
用txt文件表示为:
其中6表示有6个节点,,9999表示无穷大(本图中最大的路径长度不超过100),其他小于9999的表示实际路径长度。。。。
(1)实现方法1:未采用最小优先级队列
![](/assets/blank.gif)
![](/assets/blank.gif)
1 /*---------------------------------------------------------- 2 *name:迪杰斯特拉算法实现 3 *data:2012-5 4 *author:lp 5 *---------------------------------------------------------*/ 6 #include<stdio.h> 7 #include<stdlib.h> 8 #define max 9999 9 void Dijkstra(int ,int,int *,int *,int **); 10 void Search(int,int,int*); 11 void main() 12 { 13 int i,j,num,v,last;//num表示点的个数,v表示起始点; 14 FILE *p; 15 //2.txt中第一个数据表示点的个数,第二个数据表示起始点; 16 //其他数据为图中点之间的可达关系,-1表示不可达 17 p=fopen("2.txt","r"); 18 if(!p) 19 { 20 printf("cannot open file 2.txt"); 21 exit(0); 22 } 23 fscanf(p,"%d",&num);//获得点的个数 24 printf("请输入起始点:"); 25 scanf("%d",&v); 26 int *d=(int*)malloc(sizeof(int)*num); 27 //prev[]用于记录最短路径中每个点的前一个点 28 int *prev=(int *)malloc(sizeof(int)*num); 29 //a[][]用于记录各个点之间的路径,-1表示不可直达,具体数据参见2.txt; 30 int **a=(int**)malloc(sizeof(int*)*num); 31 for(i=0;i<num;i++) 32 a[i]=(int*)malloc(sizeof(int)*num); 33 for(i=0;i<num;i++) 34 for(j=0;j<num;j++) 35 fscanf(p,"%d",&a[i][j]); 36 37 Dijkstra(v,num,prev,d,a); 38 printf("请输入需要达到的终点(不大于%d): ",num-1); 39 scanf("%d",&last); 40 if(d[last]==max){} 41 else 42 printf("起始点%d到达终点%d的路径长度为:%d\n",v,last,d[last]); 43 Search(v,last,prev); 44 45 } 46 void Dijkstra(int v,int num,int *prev,int *d,int **a) 47 { 48 //d[]用于记录起始点到达终点的最短路径 49 //s[]用于记录节点是否已经加入到S(S:已经求的的最短路径的终点的集合) 50 //prev[i]用于记录从起始节点开始到达i节点的最短路径中i节点的前一个节点 51 int i,j; 52 int *s=(int*)malloc(sizeof(int)*num);//s[i]=1表示i点已经为S中的点; 53 for(i=0;i<num;i++)//初始化的d[],s[],prev[]; 54 { 55 s[i]=0; 56 d[i]=a[v][i]; 57 if(d[i]<max) 58 prev[i]=v; 59 else prev[i]=-1; 60 } 61 d[v]=0; 62 s[v]=1; 63 for(i=1;i<num;i++) 64 { 65 int tmp=max; 66 int k=v; 67 for(j=0;j<num;j++)//得出一个V-S中的节点放入到S中。 68 if((!s[j])&& d[j]<tmp)//找到d[]最小的点。。。 69 { 70 k=j; 71 tmp=d[j]; 72 } 73 s[k]=1;//k节点放入S中 74 for(j=0;j<num;j++)//更新d[]和prev[] 75 { 76 if((!s[j])&& a[k][j]<max) 77 { 78 int newdist; 79 newdist=d[k]+a[k][j]; 80 if(newdist<d[j]) 81 { 82 d[j]=newdist; 83 prev[j]=k; 84 } 85 } 86 } 87 } 88 } 89 //Search函数主要利用prev[]得出节点v到节点last的最短路径上的点, 90 //prev[]的值在Dijkstra函数中已经得到,,,, 91 void Search(int v,int last,int*prev) 92 { 93 if(prev[last]==-1) 94 { 95 printf("起始点%d不可达终点%d \n",v,last); 96 exit(0); 97 } 98 else 99 { 100 printf("起始点点%d到达终点%d的路径为: ",v,last); 101 printf("%d <-- ",last); 102 int k=prev[last]; 103 while(k>v) 104 { 105 printf("%d <-- ",k); 106 k=prev[k]; 107 } 108 printf("%d\n",v); 109 } 110 }
(2)实现方法2:采用最小优先级队列
(1)数据结构,严蔚敏。
(2):http://2728green-rock.blog.163.com/blog/static/43636790200901211848284/
(3):http://hi.baidu.com/wangziming/blog/item/d352be19d53e554642a9ad62.html
(4):http://blog.csdn.net/zrjdds/article/details/6728332
【算法导论】第24章迪杰斯特拉算法相关推荐
- 《算法导论》24.3-Dijkstra(迪杰斯特拉)算法(含C++代码)
一.相关含义 1.Dijkstra算法在运行过程中维持的关键信息是一组结点集合S.从源结点s到该集合中每个结点之间的最短路径已经被找到.算法重复从结点集V- S中选择最短路径估计最小的结点u,将u加入 ...
- 【算法杂谈】LJX的迪杰斯特拉算法报告
迪杰斯特拉(di jie qi)算法 这里有一张图: 假设要求从1号节点到5号节点的最短路.那么根据迪杰斯特拉算法的思想,我们先看: 节点1,从节点1出发的一共有3条路,分别是1-6.1-3.1-2. ...
- python写算法求最短路径,Python实现迪杰斯特拉算法并生成最短路径的示例代码
def Dijkstra(network,s,d):#迪杰斯特拉算法算s-d的最短路径,并返回该路径和代价 print("Start Dijstra Path--") path=[ ...
- 算法与数据结构(六) 迪杰斯特拉算法的最短路径(Swift版)
上篇博客我们详细的介绍了两种经典的最小生成树的算法,本篇博客我们就来详细的讲一下最短路径的经典算法----迪杰斯特拉算法.首先我们先聊一下什么是最短路径,这个还是比较好理解的.比如我要从北京到济南,而 ...
- C++迪杰斯特拉算法求最短路径
一:算法历史 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以 ...
- dijkstra算法_最短路径问题——迪杰斯特拉算法(Dijkstra)
假期过长,导致停更了好长时间,复习一道算法题找找感觉. 前段时间看到一篇文章,里面提到了统治世界的十大算法,其中之一就是迪杰斯特拉算法(Dijkstra),该算法主要解决的"最短路径&quo ...
- DijkstraAlgorithm(迪杰斯特拉算法)
迪杰斯特拉(Dijkstra)算法介绍 迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个结点到其他结点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到 ...
- 迪杰斯特拉算法python实现
回顾下最短路径的地杰斯特拉算法 迪杰斯特拉算法是求从某一个起点到其余所有结点的最短路径,是一对多的映射关系,是一种贪婪算法 示例: 算法实现流程思路: 迪杰斯特拉算法每次只找离起点最近的一个结点,并将 ...
- 图解迪杰斯特拉算法(最短路径问题)
文章目录 一.单源最短路径问题 二.迪杰斯特拉算法 2.1 什么是迪杰斯特拉算法 2.2 迪杰斯特拉算法的步骤 2.2.1 基本步骤 2.2.2 图解演示 2.3 迪杰斯特拉算法的代码实现 一.单源最 ...
最新文章
- iOS的一些常用性能优化,和内存优化的方法
- 如何在DataFrame索引某一行
- android 双 webview,Android webview加载页面
- about osgeo中国
- codeforces 96A-C语言解题报告
- sqlserver 单条update 特别慢_vacuum full执行慢怎么办?
- 全军出击机器人进房间_科沃斯扫地机器人T8 POWER/MAX开箱测评推荐
- 使用opencv-python画OpenCV LOGO
- VGG11、VGG13、VGG16、VGG19网络结构图
- euraka resttemplate
- 电脑重启只剩下c盘怎么办_电脑突然只剩下c盘了怎么办?
- 路由器单区域 OSPF 基本配置
- 数学建模常用算法—灰色预测
- 搜索引擎的目标是什么?
- 【分页存储管理】将十六进制的虚拟地址0A5C、103C、4251转换成物理地址
- 菜刀webshell特征分析
- C# = Lambda表达式理解
- C++ -- 基于多态的后宫管理系统(其实就是职工管理或者图书管理系统根据我自己的需求改编,毕竟追我的人太多了,要好好管理一下)
- oracle3个重要角色,Oracle 用户及角色 介绍
- 进制数与字符串之间的转换