ImageVerifierCode 换一换
格式:DOCX , 页数:12 ,大小:133.69KB ,
资源ID:4905043      下载积分:12 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4905043.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(实习三 求最短路径.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

实习三 求最短路径.docx

1、实习三 求最短路径实习三1.需求分析:【问题描述】:设计一个算法,求图中一个源点到其他各顶点的最短路径。【基本要求】:(1)以邻接表作为存储结构。(2)用Dijkstra算法求最短路径。(3)按长度非递减次序打印输出最短路径的长度及相应路径。【开发环境】:系统:windows7编程软件:VC+6.02.设计:邻接表是一种链式存储结构。在邻接表中,对图中每个顶点建立一个单链表,第i个单链表中的结点表示依附于顶点Vi的边(对有向图是以顶点Vi为尾的弧)。每个结点由3个域组成,其中邻接点域(dest)指示与顶点Vi邻接的点在图中的位置,链域(next)指示下一条边或弧的结点;数据域(weight)存

2、储和边或弧相关的信息,如权值等。所以一开始必须先定义邻接表的边结点类型以及邻接表类型,并对邻接表进行初始化,然后根据所输入的相关信息,包括图的顶点数、边数、是否为有向,以及各条边的起点与终点序号,建立图的邻接表。图的邻接表建立后,利用狄克斯特拉算法求出最短路径。狄克斯特拉算法的思想:设置两个顶点的集合S和T,集合S中存放已找到最短路径的顶点,集合T中存放当前还未找到最短路径的顶点。初始状态时,集合S中只包含源点,设为,然后从集合T中选择到源点路径长度最短的顶点u加入到集合S中,集合S中每加入一个新的顶点u,都要修改源点到集合T中剩余顶点的当前最短路径长度值,集合T中各顶点的新的当前最短路径长度

3、值为原来的当前最短路径长度值与从源点过顶点u到达该顶点的路径长度中的较小者。此过程不断重复,直到集合T中的顶点全部加入到集合S中为止。具体思想 如下所示的有向图 跟据如上图所示的有向图,建立如下图所示的邻接表存储结构,数组的data域存储图的顶点信息,source域存储该顶点在数组下标,这个下标也是所有以该顶点为狐尾的边在数组中的下标,adj域为该顶点的邻接顶点单链表的头指针。其中结点结构体定义如下:typedef struct Node int dest;/连接表的弧头顶点序号 int weight; struct Node *next;/单链表的下一个结点指针Edge;/邻接边单链表的结点

4、结构体typedef struct DataType data;/顶点数据元素 int source;/邻接边的狐尾顶点序号 Edge *adj;/邻接边的头指针AdjLHeight;typedef struct AdjLHeight aMaxVertices;/邻接表数组 int numOfVerts;/顶点个数 int numOfEdges;/边个数AdjLGraph;/连接表结构体typedef struct int row;/行下标 int col;/列下标 int weight;/权值RowCol;/边信息结构体用邻接表构建图完成后,Dijkstra算法求最短路径如下: void D

5、ijkstra(AdjLGraph *G,int v0,int distance,int path)/带权图G从下标v0顶点到其他顶点的最短距离distance和最短路径下标path int n=G-numOfVerts;/顶点个数 int *s=(int *)malloc(sizeof(int)*n); int minDis,i,j,u; Edge *p,*q; p=G-av0.adj; while(p!=NULL) /顶点能一次到达的,路径长度为其权值 i=p-dest; distancei=p-weight; pathi=v0; p=p-next; for(i=0;in;i+) /顶点一

6、次不能到达的,路径长度为MaxWeight si=0; if(pathi!=v0) pathi=-1; distancei=MaxWeight; sv0=1;/将序号v0包含在集合s内 distancev0=0;/顶点自己到自己的路径为0 for(i=0;in;i+) minDis=MaxWeight; for(j=0;jn;j+) if(sj=0 & distancejau.adj;/从第au个点开始 while(q!=NULL) if(sq-dest=0 & q-weight weightdest) /若顶点通过几次到该点的和的权值小于一次到该点的权值,则修改其到该点的权值 distanc

7、eq-dest=distanceu+q-weight; pathq-dest=u; q=q-next; 3.调试分析 首先以邻接表作为图的存储结构,其中邻接表创建图函数课本上已经给出,实现起来比较简单,重要的是Dijkastra算法求最短路径。其时间复杂度为T()。首先用充分了解Dijkastra算法思想,其中距离标号uj:记录的是从起点到该节点的最短路长度的上界。前趋标号pred(j):当取到uj时,节点j前面的那个直接前趋(标号)。算法通过不断改变这些标号进行秩代计算。算法结束时,距离标号表示起点到节点的最短路长度。前趋标号记录着最短路路径。调试过程中顶点到其本身为所设定的最大值而不是零,

8、调试发现设置一个distancev0=0,便可以解决该问题。开始时v0在集合S中,然后在所有的不在S集合中的顶点之中,选取distancei为最小的一个,设为u;将选出的终点序号u并入S集合中。4.用户手册 在VC+6.0中运行该程序后,便可通过Dijkstra算法求出顶点(本程序选取的顶点为1)到其他点的最短路径。5.测试结果 6.源代码Dijkastra.h.typedef struct Node int dest;/连接表的弧头顶点序号 int weight; struct Node *next;/单链表的下一个结点指针Edge;/邻接边单链表的结点结构体typedef struct D

9、ataType data;/顶点数据元素 int source;/邻接边的狐尾顶点序号 Edge *adj;/邻接边的头指针AdjLHeight;typedef struct AdjLHeight aMaxVertices;/邻接表数组 int numOfVerts;/顶点个数 int numOfEdges;/边个数AdjLGraph;/连接表结构体typedef struct int row;/行下标 int col;/列下标 int weight;/权值RowCol;/边信息结构体void AdjInitiate(AdjLGraph *G)/初始化图G int i; G-numOfEdge

10、s=0; G-numOfVerts=0; for(i=0;iai.source=i;/置邻接边的弧头顶点序号 G-ai.adj=NULL; void InsertVertex(AdjLGraph *G,int i,DataType vertex)/在图G中的第i(0=i=0 & iai.data=vertex;/存储顶点数据元素vertex G-numOfVerts+;/个数加1 else printf(顶点越界);void InsertEdge(AdjLGraph *G,int v1,int v2,int weight)/在图G中加入边 Edge *p; if(v1=G-numOfVerts

11、 | v2=G-numOfVerts) printf(参数v1或v2越界出错!); return; p=(Edge *)malloc(sizeof(Edge);/申请邻接边单链表结点空间 p-dest=v2;/置邻接边弧头序号 p-weight=weight; p-next=G-av1.adj;/新结点插入单链表的表头 G-av1.adj=p;/头指针指向新的单链表表头 G-numOfEdges+;/边个数加1void DeleteEdge(AdjLGraph *G,int v1,int v2)/删除图G中的边 Edge *curr,*pre; if(v1=G-numOfVerts | v2=

12、G-numOfVerts) printf(参数v1或v2越界出错!); return; pre=NULL; curr=G-av1.adj; while(curr!=NULL & curr-dest != v2) /在v1顶点的邻接边单链表中查找v2顶点 pre=curr; curr=curr-next; /删除邻接边 if(curr != NULL & curr-dest = v2 & pre=NULL) /当邻接边的结点是单链表的第一个结点时 G-av1.adj=curr-next; free(curr); G-numOfEdges-; else if(curr != NULL & curr

13、-dest=v2 & pre!=NULL) /当邻接边的结点不是单链表的第一个结点时 pre-next=curr-next; free(curr); G-numOfEdges-; else printf(边不存在!);/当邻接边不存在时 void AdjDestroy(AdjLGraph *G)/撤销图G中的所有单链表占用的存储空间 int i; Edge *p,*q; for(i=0;i numOfVerts;i+) p=G-ai.adj; while(p!=NULL) q=p-next; free(p); p=q; void CreatGraph(AdjLGraph *G ,DataTyp

14、e v,int n,RowCol d,int e)/创建有n个顶点e条边的图G/顶点信息存放在数组v中,边信息存放在数组d中 int i,k; AdjInitiate(G);/初始化 for(i=0;in;i+) InsertVertex(G,i,vi);/插入顶点 for(k=0;knumOfVerts;/顶点个数 int *s=(int *)malloc(sizeof(int)*n); int minDis,i,j,u; Edge *p,*q; p=G-av0.adj; while(p!=NULL) /顶点能一次到达的,路径长度为其权值 i=p-dest; distancei=p-weig

15、ht; pathi=v0; p=p-next; for(i=0;in;i+) /顶点一次不能到达的,路径长度为MaxWeight si=0; if(pathi!=v0) pathi=-1; distancei=MaxWeight; sv0=1;/将序号v0包含在集合s内 distancev0=0;/顶点自己到自己的路径为0 for(i=0;in;i+) minDis=MaxWeight; for(j=0;jn;j+) if(sj=0 & distancejau.adj;/从第au个点开始 while(q!=NULL) if(sq-dest=0 & q-weight weightdest) /若

16、顶点通过几次到该点的和的权值小于一次到该点的权值,则修改其到该点的权值 distanceq-dest=distanceu+q-weight; pathq-dest=u; q=q-next; main.cpp#include#define MaxVertices 10#define MaxWeight 10000 #includetypedef int DataType;#includeDijkastra.hvoid main() AdjLGraph G; DataType a=1,2,3,4,5,6; RowCol d=0,1,20,0,2,15,1,0,2,1,4,10,1,5,30,2,1,4,2,5,10,4,3,15,5,3,4,5,4,10; int distance6,path6; int i,n=6,e=10; CreatGraph(&G,a,n,d,e); Dijkstra(&G,0,distance,path); printf(用Dijkstra算法求得从顶点%d到其他各顶点的最短距离为:n,G.a0.data); for(i=0;in;i+) printf(到顶点%d的最短距离为%dn,G.ai.data,distancei);

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1