单源结点最短路径.docx
- 文档编号:25579277
- 上传时间:2023-06-09
- 格式:DOCX
- 页数:17
- 大小:82.15KB
单源结点最短路径.docx
《单源结点最短路径.docx》由会员分享,可在线阅读,更多相关《单源结点最短路径.docx(17页珍藏版)》请在冰豆网上搜索。
单源结点最短路径
单源结点最短路径
一、题目
单源结点最短路径问题。
二、问题描述
求从有向图的某一结点出发到其余各结点的最短路径。
三、基本要求
(1)有向图采用邻接矩阵表示。
(2)单源结点的最短路径问题采用狄克斯特拉算法。
(3)输出有向图中从源结点到其余各结点的最短路径和最短路径值。
四、测试数据
测试数据为如下图所示的有向带权图,以结点v1作为源结点,求从结点v1到其余各结点的最短路径和最短路径的长度值。
图有向带权图
五、算法思想
1.算法流程图
算法流程图
(2)算法分析
按已给有向图构造出图G结构体,顺序表存储顶点信息,矩阵存储邻接矩阵信息,记录边的条数;选择v1为起始顶点,用狄克斯特拉算法求v1顶点到其他各个顶点的最短路径值和最短距离。
将所有的顶点分为S、T两类,S用来存放已知最短路径的顶点。
而T存放未知最短路径的顶点。
如果起始点(v1)到某个相邻顶点的最短距离已经求出,比如v1-v2的距离。
那么就把v2归入S,其余的不能直接算出最短距离的则要归入T。
刚开始的S只有起始点一个,随着算法的继续,首先将起始点相邻的点归入到S,知道最后一个顶点归入S。
六、模块划分
1.创建图
(1)算法流程
创建图流程
(2)求得G图结构如下图所示:
顺序表
V1
V2
V3
V4
V5
V6
邻接矩阵
边的条数:
11
2.求最短路径和最短距离
算法流程图
(1)求得最短距离矩阵如下
(2)求得最短距离矩阵如下
七、数据结构
1.结构体定义
(1)图的结构体定义
typedefstruct
{
SeqListVertices;//存放顶点的顺序表
intedge[MaxVertices][MaxVertices];//存放边的邻接矩阵
intnumOfEdges;//边的条数
}AdjMGraph;//图的结构体定义
(2)边信息结构体定义
typedefstruct
{
introw;//行下标
intcol;//列下标
intweight;//权值
}RowColWeight;//边信息结构体定义
八、源程序
1.子函数AdjMGraph.h
/**邻接矩阵存储存储结构下图操作的实现**/
#ifndefADJMGRAPH_H_INCLUDED
#defineADJMGRAPH_H_INCLUDED
#include"SeqList.h"//包含顺序表头文件
typedefstruct
{
SeqListVertices;//存放顶点的顺序表
intedge[MaxVertices][MaxVertices];//存放边的邻接矩阵
intnumOfEdges;//边的条数
}AdjMGraph;//图的结构体定义
/**初始化有n个顶点的顶点顺序表和邻接矩阵**/
voidInitiate(AdjMGraph*G,intn)
{
inti,j;
for(i=0;i for(j=0;j { if(i==j)G->edge[i][j]=0; elseG->edge[i][j]=MaxWeight;//MaxWeight表示无穷大 } G->numOfEdges=0;//边的条数置为0 ListInitiate(&G->Vertices);//顺序表初始化 } /**在图中增加一个顶点**/ voidInsertVertex(AdjMGraph*G,DataTypevertex) //在图中插入顶点vertex { ListInsert(&G->Vertices,G->Vertices.size,vertex);//顺序表尾插入 } /**在图中增加一条有向边**/ voidInsertEdge(AdjMGraph*G,intv1,intv2,intweight) //在图G中插入边 { if(v1<0||v1>=G->Vertices.size||v2<0||v2>=G->Vertices.size) { printf("参数v1或v2越界出错! \n"); return; } G->edge[v1][v2]=weight; G->numOfEdges++; } /**在图中取消一条有向边**/ voidDeleteEdge(AdjMGraph*G,intv1,intv2) //在图G中删除边 { if(v1<0||v1>=G->Vertices.size||v2<0|| v2>=G->Vertices.size||v1==v2) { printf("参数v1或v2出错\n"); return; } if(G->edge[v1][v2]==MaxWeight||v1==v2) { printf("该边不存在! \n"); return; } G->edge[v1][v2]=MaxWeight; G->numOfEdges--; } /**取第一个邻接顶点**/ intGetFirstVex(AdjMGraphG,intv) //在图G中需要序号为V的顶点的第一个邻接顶点 //如果这样的邻接顶点存在,则返回该邻接顶点的序号,否则返回-1 { intcol; if(v<0||v>=G.Vertices.size) { printf("参数v1越界! \n"); return-1; } for(col=0;col if(G.edge[v][col]>0&&G.edge[v][col] returncol; return-1; } /**取下一个邻接顶点**/ intGetNextVex(AdjMGraphG,intv1,intv2) //在图G中寻找V1顶点的邻接顶点V2的下一个邻接顶点 { intcol; if(v1<0||v1>=G.Vertices.size||v2<0||v2>=G.Vertices.size) { printf("参数v1或v2越界出错! \n"); return-1; } for(col=v2+1;col if(G.edge[v1][col]>0&&G.edge[v1][col] returncol; return-1; } #endif//ADJMGRAPH_H_INCLUDED 2.子函数AdjMGraphCreate.h /**图的创建函数**/ #ifndefADJMGRAPHCREATE_H_INCLUDED #defineADJMGRAPHCREATE_H_INCLUDED typedefstruct { introw;//行下标 intcol;//列下标 intweight;//权值 }RowColWeight;//边信息结构体定义 voidCreatGraph(AdjMGraph*G,DataTypeV[],intn,RowColWeightE[],inte) //在图G中出入n个顶点信息V和e条边的信息E { inti,k; Initiate(G,n);//顶点顺序表初始化 for(i=0;i InsertVertex(G,V[i]);//插入顶点 for(k=0;k InsertEdge(G,E[k].row,E[k].col,E[k].weight);//插入边 } #endif//ADJMGRAPHCREATE_H_INCLUDED 3.子函数Dijkstra.h #ifndefDIJKSTRA_H_INCLUDED #defineDIJKSTRA_H_INCLUDED #defineN6 voidDijkstra(AdjMGraphG,intv1,intdistance[],intpath[][N]) //带权图G从下标v1顶点到其他顶点的最短距离distance和最短路径下标path { intn=G.Vertices.size; int*s=(int*)malloc(sizeof(int)*n); intminDis,i,j,u,k; //初始化 for(i=0;i { path[i][0]=v1; for(j=1;j path[i][j]=-1; } for(i=0;i { distance[i]=G.edge[v1][i]; s[i]=0; if(i! =v1&&distance[i] path[i][1]=i; } //标记顶点v0已从集合T加入到集合S中 s[v1]=1; //在当前还未找到最短路径的顶点集中选取具有最短距离的顶点u for(i=1;i { minDis=MaxWeight; for(j=0;j if(s[j]==0&&distance[j] { u=j; minDis=distance[j]; } //当已不存在路径时,算法结束。 此句对非连通图是必需的 if(minDis==MaxWeight)return; //标记顶点u已从集合T加入到集合S中 s[u]=1; //修改从v0到其他顶点的最短路径和最短距离 for(j=0;j { if(s[j]==0&&G.edge[u][j] { //顶点v0经顶点U到其他顶点的最短距离和最短路径 distance[j]=distance[u]+G.edge[u][j]; for(k=0;path[u][k]! =-1;k++) { path[j][k]=path[u][k]; } path[j][k++]=j; path[j][k]=-1; } } } } #endif//DIJKSTRA_H_INCLUDED 4.子函数SeqList.h #ifndefSeqList_H #defineSeqList_H typedefstruct { DataTypelist[MaxSize];//DataType这个在你用的时候可以去定义它的类型 intsize;//指这个表的总长度 }SeqList;//定义抽象数据类型SeqList voidListInitiate(SeqList*L)//初始化顺序表L { L->size=0;//定义初始元素个数 } intListLength(SeqListL) { returnL.size; } intListInsert(SeqList*L,inti,DataTypex) //在顺序表L的位置i(0<=i<=size为当前数据元素个数)插入数据元素值x //插入成功返回1,否则返回0 { intj; if(L->size>=MaxSize) { printf("表已满无法插入! \n"); return0; } elseif(i<0||i>L->size) { printf("参数i不合法! \n"); return0; } else { for(j=L->size;j>i;j--) { L->list[j]=L->list[j-1]; } L->list[i]=x; L->size++; return1; } } intListDelete(SeqList*L,inti,DataType*x) //删除顺序表L中位置i上的数据元素并保存到x中 //插入成功返回1,否则返回0 { intj; if(L->size<=0) { printf("表已空无法插入! \n"); return0; } elseif(i<=0||i>L->size-1) { printf("参数i不合法! \n"); return0; } else { *x=L->list[i]; for(j=i+1;j<=L->size-1;j++) L->list[j-1]=L->list[j]; L->size--; return1; } } intListGet(SeqListL,inti,DataType*x) //取顺序表L中第i个元素的值,取到则返回1,否则返回0 { if(i<0||i>L.size-1) { printf("参数i不合法! \n"); return0; } else { *x=L.list[i]; return1; } } intListNotEmpty(SeqListL) //判断该表是否为空 //如果表的总长度小于等于0,则说明该表为空,返回1 { if(L.size<=0) return0; else return1; } #endif 5.主函数 #include #include #include typedefcharDataType; #defineMaxSize10//定义顺序表数组的最大值 #defineMaxVertices30//定义顶点的最大值 #defineMaxWeight10000//定义无穷大的具体值 #include"AdjMGraph.h" #include"AdjMGraphCreate.h" #include"Dijkstra.h" intmain() { AdjMGraphg; chara[]={'1','2','3','4','5','6'}; RowColWeightrcw[]={{0,1,10},{0,2,12},{1,3,16},{1,4,25},{2,0,4},{2,1,3}, {2,3,12},{2,5,8},{3,4,7},{5,3,2},{5,4,10}}; inti,n=6,e=11,j; intdistance[6],path[6][6]; CreatGraph(&g,a,n,rcw,e); Dijkstra(g,0,distance,path); printf("从顶点v%c到其他各顶点的最短距离为: \n",g.Vertices.list[0]); for(i=0;i printf("到顶点v%c的最短距离为%d\n",g.Vertices.list[i],distance[i]); printf("\n从顶点v%c到其他各顶点最短路径为: \n",g.Vertices.list[0]); for(i=0;i { printf("\n到顶点v%c的最短路径为: ",g.Vertices.list[i]); for(j=0;j if(path[i][j]! =-1) printf("v%c",g.Vertices.list[path[i][j]]); } return0; } 九、测试情况 程序运行结果
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 结点 路径