本文记录一下dijkstra算法的实现,图用邻接矩阵表示,假设图为无向图。而且连通,有向图,不连通图的做法相似。

算法简述:

  1. 首先确定“单源”的源。假设是第0个顶点。

  2. 维护三个数组dist[], color[], path[]。设其下标分别为0…i…n-1:

      dist[] 表示源点到顶点i的最短距离,在初始化时,假设源点到顶点i有路径,则初始化为路径的权重。否则初始化为INT_MAX。

      color[] 数组事实上表示两个集合,即color[i]值为1的集合表示已经确定最短路径的点的集合,color[i]值为0表示没有确定最短路径的点的集合。初始化为将源点的color设置为1,其余点设置为0。

      path[]数组存储到顶点i的路径,假设path[i]=3,path[3]=2,paht[2]=0,则这条最短路径是0->2->3->i,与数组给出的顺序是逆序。

  3. 依次从dist[]数组中选一个最小的dist值,假设顶点的坐标为index,这个dist值即为终于确定的最短距离的点,更新这个点的color值为1。以下一个操作是dijkstra算法的重点。也仅仅有这么一个重点操作,即:在没有确定最短距离的集合中(即color值为0的点的集合),假设源点到index的距离,加上index到这些点的距离小于原来的dist值,则更新dist值,同一时候更新path值。

  4. 反复第3个操作,直到color值为0的集合为空。

以下给出c语言实现代码,方法都出了凝视,这里不再说明, 假设不足之处请提出(使用的默认的图例如以下):

#include <stdlib.h>
#include <stdio.h>
#include <limits.h> int n;
int source = 0; //求从第0个节点到其它节点的最短路径
int* dist;
int* path;
int* color; //颜色为1说明已经找到最短路径。为-1说明没找到最短路径 //获得默认的图,即上图所看到的。使用邻接矩阵表示
int** get_graph(){
int** matrix;
int i,j;
int start,end,weight; printf("input vertex num:\n");
scanf("%d",&n); matrix = (int**)malloc(sizeof(int*)*n); for(i=0;i<n;i++){
matrix[i] = (int*)malloc(sizeof(int)*n);
for(j=0;j<n;j++){
if(i!=j)
matrix[i][j] = INT_MAX;
else
matrix[i][j] = 0;
}
} printf("input start end weight, stop by -1\n"); for(;;){
scanf("%d",&start);
if(start==-1){
break;
}
scanf("%d %d",&end,&weight);
matrix[start][end] = weight;
matrix[end][start] = weight;
}
return matrix;
} //使用迪杰斯特拉算法求单源最短路径
void single_source_shortest_path(int** matrix,int source){ int i,j,index,min; dist = (int*)malloc(sizeof(int)*n);
color = (int*)malloc(sizeof(int)*n);
path = (int*)malloc(sizeof(int)*n); //初始化最短路径:
//直接相连的初始化为权重,不直接相连的初始化为INT_MAX
for(i=0;i<n;i++){
dist[i] = matrix[source][i];
color[i] = 0;
if(i!=source && dist[i]!=INT_MAX){
path[i] = source;
}else{
path[i] = -1;
}
} color[source] = 1;
path[source] = 0; //找一个从源点到其它节点最短的路径
for(j=0;j<n;j++){
min = INT_MAX;
index = -1;
for(i=0;i<n;i++){
if(!color[i] && dist[i]<min){
index = i;
min = dist[i];
}
} if(index==-1){ //全部定点的终于距离都确定
break;
} color[index] = 1; //标记为已经确定最短距离的定点 //接下来更新到每一个未确定最短距离的定点的距离
//假设源点到刚刚加入的节点的最短距离+刚刚加入的节点的距离到未确定最短距离的定点的距离 < 源最短距离,则更新
for(i=0;i<n;i++){
if(!color[i] && matrix[index][i]!=INT_MAX && dist[index]+matrix[index][i]<dist[i]){
dist[i] = dist[index]+matrix[index][i];
path[i] = index;
}
}
}
} int main(){ int** matrix = get_graph();
int i,t; single_source_shortest_path(matrix,source); printf("\n");
for(i=0;i<n;i++){
printf("%d: %d,and the path is(inverse order): %d ",i,dist[i],i);
t = path[i];
while(1){
printf(" %d ",t);
if(t==0){
break;
}
t = path[t];
}
printf("\n");
} printf("\n");
return EXIT_SUCCESS;
}

执行结果例如以下:

单源最短路径 dijkstra算法实现的更多相关文章

  1. 单源最短路径Dijkstra算法,多源最短路径Floyd算法

    1.单源最短路径 (1)无权图的单源最短路径 /*无权单源最短路径*/ void UnWeighted(LGraph Graph, Vertex S) { std::queue<Vertex&g ...

  2. 单源最短路径——dijkstra算法

    dijkstra算法与prim算法的区别   1.先说说prim算法的思想: 众所周知,prim算法是一个最小生成树算法,它运用的是贪心原理(在这里不再证明),设置两个点集合,一个集合为要求的生成树的 ...

  3. 单源最短路径——Dijkstra算法学习

    每次都以为自己理解了Dijkstra这个算法,但是过没多久又忘记了,这应该是第4.5次重温这个算法了. 这次是看的胡鹏的<地理信息系统>,看完之后突然意识到用数学公式表示算法流程是如此的好 ...

  4. 单源最短路径-Dijkstra算法

    1.算法标签 贪心 2.算法描述 具体的算法描述网上有好多,我觉得莫过于直接wiki,只说明一些我之前比较迷惑的. 对于Dijkstra算法,最重要的是维护以下几个数据结构: 顶点集合S : 表示已经 ...

  5. [数据结构与算法-15]单源最短路径(Dijkstra+SPFA)

    单源最短路径 问题描述 分别求出从起点到其他所有点的最短路径,这次主要介绍两种算法,Dijkstra和SPFA.若无负权优先Dijkstra算法,存在负权选择SPFA算法. Dijkstra算法 非负 ...

  6. matlab练习程序(单源最短路径Dijkstra)

    图的相关算法也算是自己的一个软肋了,当年没选修图论也是一大遗憾. 图像处理中,也有使用图论算法作为基础的相关算法,比如图割,这个算法就需要求最大流.最小割.所以熟悉一下图论算法对于图像处理还是很有帮助 ...

  7. 单源最短路径---Bellman-Ford算法

    传送门: Dijkstra Bellman-Ford SPFA Floyd 1.Dijkstra算法的局限性 像上图,如果用dijkstra算法的话就会出错,因为如果从1开始,第一步dist[2] = ...

  8. 洛谷P3371单源最短路径Dijkstra版(链式前向星处理)

    首先讲解一下链式前向星是什么.简单的来说就是用一个数组(用结构体来表示多个量)来存一张图,每一条边的出结点的编号都指向这条边同一出结点的另一个编号(怎么这么的绕) 如下面的程序就是存链式前向星.(不用 ...

  9. 单源最短路径Dijkstra和优先级算法

    百度百科:迪杰斯特拉算法. 代码实现如下: import java.util.Comparator; import java.util.PriorityQueue; import java.util. ...

随机推荐

  1. G彩娱乐网一个程序员到一个销售高手的心路历程

    0.引言 我大学本科读的是理工科,后来毕业以后,我逐渐走上了程 序员的道路.每天面对电脑一行一行的敲代码,这被我们程序员们戏称为"搬砖头",因为我们所做的事跟民工搬砖头砌墙本质上是 ...

  2. NHibernate 慎用Session.Merge

    Session.Merge其意思有两个步骤, 一般用法: Session.Merge(obj); 1. 从当前的Session中获取obj对象, 如果未获取到则从数据库获取. 2. 把程序中的obj的 ...

  3. 使用jquery ajaxForm提交表单

    一.首先引用Jquery <script src="~/Scripts/jquery-1.9.1.min.js"></script> <script ...

  4. Linux 文件系统模型

    声明:本文仅限于 cnblogs 发布,其他第三方网站均为盗版,原文地址:Linux 文件系统模型 在 Linux 环境下有过一些经历的同学可能都会遇到一个问题,这个问题就是往机器上插入 U盘 或者其 ...

  5. Python学习——列表

    定义:1.列表(list)是由一系列特定顺序排列的元素组成,可以包含字母,数字或者将任何东西加入列表. 2.列表的标识符号为 [ ],函数名称为list 3.列表是有序的 相关概念: 元素:列表中的值 ...

  6. 将非常规Json字符串转换为常用的json对象

    如下所示,这是一个已经转换为Json对象的非常规Json字符串,原来是一个Json类型的字符串,在转换为Json对象时,查询资料发现有两种转换法,.parse()和.eval()方法,但是前辈们都极其 ...

  7. 使用springboot完成密码的加密解密

    现今对于大多数公司来说,信息安全工作尤为重要,就像京东,阿里巴巴这样的大公司来说,信息安全是最为重要的一个话题,举个简单的例子: 就像这样的密码公开化,很容易造成一定的信息的泄露.所以今天我们要讲的就 ...

  8. MarkdownPad2使用高亮插件

    MarkdownPad 2有插入代码块的功能,但样式却不尽人意,但又不想换个编辑器,找了挺多相关资料,最后在MarkdownPad 2集成prettify高亮插件. 如下相关资料: [HTML] Pr ...

  9. struts2的简单执行过程

    struts2是最近刚学的一个框架,想通过写篇文章来加深下印象,这也是本篇博文产生的由来,下面进入正题 Struts2本身是一个挺简单的框架,我们通过写一个登陆的过程来具体描述下其执行过程 1.首先我 ...

  10. python 保存命令执行结果

    保存命令执行的结果需哟使用os.popen("系统命令").read(),然后使用变量赋值输出即可 >>> result = os.popen("df ...