数据结构设计说明书单源点最短路径算法的实现学生姓名王文刚学号1418064056班级网络1402成绩指导教师数学与计算机科学学院年月日课程设计任务书20 —20 学年第学期课程设计名称:数据结构课程设计课程设计题目:单源点最短路径算法的实现完成期限:自年月日至年月日共 2 周设计内容:1.任务说明2.要求3.参考资料指导教师:教研室负责人:课程设计评阅摘要设计了一求解最短路径的方法,该方法具有在输入的途中查找两个顶点之间的最短路径的功能。
本方法采用VC++作为软件开发环境,采用Dijkstar函数来求取顶点之间的最短路径。
,用户可以自己输入各个地点及其之间的距离,便于用户在不同情况下均可使用。
关键词:最短路径;Dijkstar;无向图;目录目录1课题描述 (2)2 需求分析 (3)3概要设计 (4)3.1 存储结构 (4)3.2 算法描述 (5)4详细设计 (6)4.1 功能模块图 (6)4.2 主函数 (6)4.3 pd函数 (7)4.4 CreateMGraph函数 (8)4.5Dijkstar函数 (9)5程序编码 (11)6程序的调试与测试 (15)8总结 (16)参考文献 (17)1.目录中可以只有一级标题2.页码右侧对齐页边距3.本页不需要页码4.以上内容仅作参考,具体章节由课程设计类型确定1课题描述随着交通的发展,人民生活水平的提高。
出门旅行变的越来越频繁,而且供暖也成为冬天不可或缺的内容。
为了节约时间和金钱,所以人们都希望找到旅行目的地的最短路径和架设暖气的最短路径。
那么如何找到最短路径呢?由于路径较多,手工计算比较麻烦,而且容易出错,因此人们用计算机语言代替手工计算求最短路径。
而在计算机语言中迪杰斯特拉算法比较常见,简洁,故人们常借助计算机程序迪杰斯特拉算法求最短路径。
这样可以广泛提高效率,容易理解。
2 需求分析3概要设计3.1 存储结构一个图的邻接矩阵表示是唯一的。
图的邻接矩阵表示,除了需要用一个二维数组存储顶点之间相邻关系的邻接矩阵外,通常还需要使用一个具有n个元素的一维数组存储顶点信息,其中下标为i的元素存储顶点vi的信息。
因此,图的邻接矩阵的存储结构定义如下: #define MVNum 50typedef struct {VertexType vexs[MVNum];Adjmatrix arcs[MVNum][MVNum];}Mgraph;图如下图3.1 无向图a b c d e fa ∞ 3 4 ∞∞∞b 3 ∞∞ 15 5 ∞c 4 ∞∞ 312 ∞d ∞ 15 3 ∞∞8e ∞ 512 ∞∞6f ∞∞∞8 6 ∞图2.1 G的邻结矩阵3.2 算法描述(1) Dijkstra算法核心是贪心,实质是按路径长度递增产生诸顶点的最短路径算法。
迪杰斯特拉算法可用自然语言描述如下:初始化S和D,置空最短路径终点集,置初始的最短路径值;S[v1]=TRUE;D[v1]=0;While(S集中的顶点数<n){开始循环,每次求的v1到某个v顶点的最短路径,并将v加到S集中;S[v]=TRUE; 更新当前最短路径及距离。
}(2)Dijkstra算法结束后,通过设置一个数组记录下一个节点的前趋节点,然后通过倒叙的方式输出该最短路径。
(3)Dijkstra算法思想为:设G=(V,E),G是带权无向图,V代表图中顶点集合,E代表图中含权重的边集合。
将全部顶点集合V分成两组,第一组为已求出最短路径的顶点集合,用S表示(初始时S中只有一个源点,以后每求得一条最短路径,就将该路径的终点加入到集合S中);第二组为其余待确定最短路径的顶点集合,用U表示。
按最短路径长度的递增次序依次把U集合的顶点逐个加入到S集合中,约束条件是保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。
算法的终止条件是集合U为空集,即集合U的顶点全部加入到集合S中。
(4)Maxint:最大整数值,表示两个不能到达的顶点。
4详细设计4.1 功能模块图如图4.1所示图4.1功能模块4.2 主函数主函数流程图如图4.2图4.2 主函数4.3 pd函数函数如图4.3所示图4.3 Pd函数4.4 CreateMGraph函数createMGraph函数如图4.4所示图4.4 createMGraph函数4.5Dijkstar函数5程序编码#include<stdio.h>#include<stdlib.h>#define MVNum 100#define Maxint 32767typedef char VertexType;typedef int Adjmatrix;typedef enum {FALSE,TRUE}boolean;typedef struct {VertexType vexs[MVNum];Adjmatrix arcs[MVNum][MVNum];}MGraph;int D1[MVNum],P1[MVNum];int D[MVNum][MVNum],P[MVNum][MVNum];int pd(MGraph *G,int &n,int &e){while((n>0)&&(e>n*(n-1)/2)){printf("你输入的顶点或边数不正确,请重新图中顶点个数和边数n,e:");scanf("%d,%d",&n,&e);}return TRUE;}CreateMGraph(MGraph *G,int n,int e){int i,j,k,w;char a,b;for(i=1;i<=n;i++)G->vexs[i]=i;for(i=1;i<=n;i++)for(j=1;j<=n;j++)G->arcs[i][j]=Maxint;G->arcs[j][i]=Maxint;printf("输入%d条边的i,j及w:\n",e);for(k=1;k<=e;k++){fflush(stdin);scanf(" %c,%c,%d",&a,&b,&w);i=a-'a'+1;j=b-'a'+1;G->arcs[i][j]=w;G->arcs[j][i]=w;}printf("无向图的存储结构建立完毕!\n");}void Dijkstra(MGraph G,int v1,int n){int D2[MVNum],P2[MVNum];int v,i,w,min;boolean S[MVNum]; // 判断该点是否到过S中,即该点是否被遍历for(v=1;v<=n;v++){S[v]=FALSE;D2[v]=G.arcs[v1][v];if(D2[v]<Maxint)P2[v]=v1;elseP2[v]=0;}D2[v1]=0;S[v1]=TRUE;for(i=2;i<=n;i++){min=Maxint;for(w=1;w<=n;w++)if(!S[w]&&D2[w]<min){v=w;min=D2[w];}S[v]=TRUE;for(w=1;w<=n;w++)if(!S[w]&&(D2[v]+G.arcs[v][w]<D2[w])){D2[w]=D2[v]+G.arcs[v][w];P2[w]=v;}}printf("最短路径----------路径\n");for(i=1;i<=n;i++){printf("%5d",D2[i]);printf("%14c",i-1+'a');v=P2[i];while(v!=0){printf("<-%c",v-1+'a');v=P2[v];}printf("\n");}}void main(){MGraph G;int n,e,v;char ch;printf("输入图中顶点个数和边数n,e:");scanf("%d,%d",&n,&e);pd(&G,n,e);//scanf("%d,%d",&n,&e);//n=r;//e=a;CreateMGraph(&G,n,e);while(1){printf("求最短路径,输入开始点v:");fflush(stdin);scanf("%c",&ch);v=ch-'a'+1;Dijkstra(G,v,n);}}6程序的调试与测试调试如图6.1所示输入:2,5a,b,5a,c,15 b,c,6 b,d,2 c,d,10a b图6.17总结本次课程设计涉及到的范围很广,让我能够比较系统的对C语言和数据结构进行一次整理和复习。
同时有了很多的体会和经验。
在这次课程设计中我体会到C语言超强的逻辑性,能够熟练使用的编译环境,也对这两门课程有了新的认识,他们既有联系,又相互区别,在编写程序过程中要灵活应用。
一开始信息是不能重复查询也就是说,整个设计过程中,遇到了很多问题,例如查询一次后退出重新运行才可以不能连续查询后来添加了一个简单的while()语句就实现了二次查询这次“求解最优路径”的课题,让我明白很多不知道的知识内容,对求解最优路径有了进一步的了解和认识。
最后感谢老师布置给我们的任务,我会更加努力的学好这方面的知识,编写出更有价值的程序。
最短路径算法关键先把已知最短路径顶点集(只有一个源点)和未知的顶点分开,然后依次把未知集合的顶点按照最短路径(这里特别强调一下是源点到该顶点的路径权重和,不仅仅是指它和父结点之间的权重,一开始就是在没有这个问题弄清楚)加入到已知结点集中。
在加入时可以记录每个顶点的最短路径,也可以在加入完毕后回溯找到每个顶点的最短路径和权重。
参考文献[1] 严蔚敏,吴伟民.数据结构(C语言版)[M].北京:清华大学出版社,2002[2] 李春葆.数据结构(C语言版)习题与解析[M]. 北京:清华大学出版社,2002[3] 钱能.C++程序设计教程[M]. 北京:清华大学出版社,2003。