单源结点最短路径.docx

上传人:b****9 文档编号:25579277 上传时间:2023-06-09 格式:DOCX 页数:17 大小:82.15KB
下载 相关 举报
单源结点最短路径.docx_第1页
第1页 / 共17页
单源结点最短路径.docx_第2页
第2页 / 共17页
单源结点最短路径.docx_第3页
第3页 / 共17页
单源结点最短路径.docx_第4页
第4页 / 共17页
单源结点最短路径.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

单源结点最短路径.docx

《单源结点最短路径.docx》由会员分享,可在线阅读,更多相关《单源结点最短路径.docx(17页珍藏版)》请在冰豆网上搜索。

单源结点最短路径.docx

单源结点最短路径

单源结点最短路径

一、题目

单源结点最短路径问题。

二、问题描述

求从有向图的某一结点出发到其余各结点的最短路径。

三、基本要求

(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中插入边,边的权为weight

{

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;

}

九、测试情况

程序运行结果

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

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

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