Dijkstra算法的实现-数据结构与算法课程设计报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
合肥学院
计算机科学与技术系
课程设计报告
2009 ~2010 学年第2 学期
课程数据结构与算法
课程设计名称Dijkstra算法的实现
学生姓名张睿辰
学号0804012044
专业班级08计科(2)班
指导教师王昆仑张贯虹
2010 年6月
Dijkstra算法的实现
一、问题分析与任务定义
1、课程设计题目:
1.1题目:对任意图,选择合适的数据结构表示图,在此基础上实现求解最短路径
的Dijkstra算法
1.2 要求:设计合理的数据结构存储图,简单有效的实现Dijkstra算法。
1.3具体任务:建立图的存储模块,建立图的输出模块,在建图后从单源点开始求最短
路径,并显示出来!
2、原始数据的输入格式:
2.1建图模块:2.1.1数字
2.2.2数字+空格+数字+空格+数字+回车
2.3显示模块:回车
3、实现功能:
3.1 建立有向图
3.2 显示存储的有向图
3.3 显示从顶点到其他各顶点的最短路径
4、测试用例:
4.1正确数据:a)顶点:3;边值信息:0 1 6;0 2 4;1 2 5;2 0 6;0 0 0;
b)顶点:0;边值信息:0 0 0;
输出结果:a) v0到v1的最短路径是6,v0到v2的最短路径是4
b) 没有最短路径
4.2错误数据:a) 顶点:a
b)顶点:2;边值信息:0 3 6;0 4 4;13 5;0 0 0;
c)顶点:3;边值信息:0 1 a;
输出结果:边值错误,请从新输入
5、问题分析:
实现本程序要解决以下几个问题:
5.1如何存储一个有向图。
5.2如何在界面中输出该有向图。
5.3如何定义起始源点。
5.4如何选择出最短路径。
5.5找到的最短路径如何输出。
二、数据结构的选择和概要设计
1、数据结构的选择:
在图的结构中,任意两个顶点之间都可能存在关系,比线性表和树要复杂。由于不存在严格的前后顺序,因而不能采用简单的数组来存储图;另一方面,如果采用链表,由于图中各顶点的度数不尽相同,最小度数和最大度数可能相差很大,如果按最大度数的
顶点来设计链表的指针域,则会浪费很多存储单元,反之,如果按照各个顶点设计不同的链表结点,则会给操作带来很大的困难。
在此我选用邻接矩阵的存储结构。采用邻接矩阵存储,很容易判断图中两个顶点是否相连,也容易求出各个顶点的度。不过任何事情都不是完美的,采用邻接矩阵存储图时,测试其边的数目,必须检查边二维数组的所有元素,时间复杂度为O (n 2),这对于顶点很多而边较少的图(稀疏图)是非常不合算的。
以邻接矩阵存储有向图,如图1中有向图G 所示,其邻接矩阵为图 2 cost 。
图2. 有向图 图2.矩阵cost
有向图的邻接矩阵cost[i][j]定义为
int cost [n][n]; 2、 概要设计
2.1对于最短路径问题:
最短路径是在实际应用中非常有用的工具,我们常见的两种最短路径是: (1)从某源点到其余各顶点之间的最短路径。 (2)每一段顶点之间的最短路径
在这里我们解决第一类问题。 2.2 Dijkstra 算法用于求最短路径:
Dijkstra 算法是按路径长度递增的次序逐步产生源点到其他顶点间的最短路径。算法建立一个顶点集合S ,初始时该集合只有源点V0,然后逐步将已求得最短路径的顶点加入到集合中,直到全部顶点都在集合S 中,算法结束。
2..3 Dijkstra 算法思想
设cost[i,j]=0,S 为已经求得最短路径的顶点集合,distance[i]数组的每个元素表示当前状态下源点V0到Vi 的最短路径。算法如下: 1) 初始化:S={V0}, distance[i]=cost[0,i]。
2) 选择一个终点Vj ,满足distance[j]=MIN{ distance[i]|Vi ∈V-S}。 3)把Vj 加入到S 中。
4)修改distance 数组元素,修改逻辑为对于所有不在S 中的顶点Vi.
20 0 50 10 ∞ 45
∞ 0 15 50 10
∞ 20 0 ∞ ∞ ∞ ∞ 15 ∞ 20 ∞ 0 35 ∞ ∞ ∞ ∞ 30 0
∞ 0
∞ 3 ∞ ∞ ∞
if(distance[j]+cost[i,j]< distance[i]) { distance[i]= distance[j] ]+cost[i,j] }
5)重复操作2)、3)、4),直到全部顶点加入到S中。
2.4 实现流程
在任意图中实现求最短路径问题,第一步是要能成功的在内存中输入图的信息,图的信息有两个,一是顶点个数,二是每两点之间的权值信息。当建立图之后,对图进行遍历才能使用Dijkstra算法求出最短路径;在完成了图的建立之后,用Dijkstra 算法的思想,从单源点开始,求出到各个顶点的最短路径,并能够实现显示功能。
程序流程图:
Dijkstra算法流程图:
三、详细设计和编码
3.1邻接矩阵的定义:
我们定义全局变量cost[][],dist[]数组,方便在各子程序中的调用,加快了程序的运行速度。int cost[MAX][MAX];
int dist[MAX];
int n;
cost二维数组用于存放邻接矩阵,每个位置代表的值为图中的权值,其余用无穷大999表示。dist为辅助数组,图中每个顶点对应该数组中的一个元素,这个元素存放当前源点到该顶点的最短路径。此时的路径指示当前结果,并不一定是最终的最短路径。随着集合S的变化,其他顶点不断地加入到集合中,可能以这些新加入的顶点为“桥梁”产生比以前路径更短的路径,dist数组元素的值是动态变化的。
n是指图中的顶点数目。
3.2结点结构体的定义:
struct
{
int num;
int pnode[MAX];
}path[MAX];
整型变量num是用来记录求V0到每个顶点的最短路径时所经过的顶点的数目。
数组pnode用来存放求V0到每个顶点的最短路径时所经过的顶点,初始为V0。
结构体数组path为从V0到各顶点的最短路径。
3.3创建带权有向图
初始化邻接矩阵cost中的值为无穷大,即任意两个顶点之间不存在路径。首先输入该有向图的顶点数n,然后依次输入各个顶点及边长(输入的顶点的序号应该小于顶点的数目)。输入0 0 0结束。定义变量contin,标志输入是否结束。若contin=1,输入继续,若contin=0,输入完成。
代码:
void creatgraph() //创建带权有向图
{
int i,j,s,e,len,contin=1;
printf("\n请输入顶点个数:");
scanf("%d",&n);
for(i=0;i { for(j=0;j cost[i][j]=up; cost[j][i]=up; //初始化所有顶点间的边值均为无穷大} cost[i][i]=0; //每个顶点到自己的边值为0