最短路径上机报告.docx
- 文档编号:27819345
- 上传时间:2023-07-05
- 格式:DOCX
- 页数:12
- 大小:34.14KB
最短路径上机报告.docx
《最短路径上机报告.docx》由会员分享,可在线阅读,更多相关《最短路径上机报告.docx(12页珍藏版)》请在冰豆网上搜索。
最短路径上机报告
最短路径上机报告
问题重述:
以书上图8-13有向带权图为例,从图中选一节点为源点,找出它到其他节点的最短路径。
基本要求:
带权图以邻接矩阵的方式存储。
测试数据:
chara[]={‘A’,’B’,’C’,’D’,’E’,’F’},
RowColWeightrow={{0,2,5},{0,3,30},{1,0,2},{1,4,8},{2,1,15},{2,5,7},{4,3,4},{5,3,10},{5,4,18}}
算法思想:
本问题的解决思想是狄克斯特拉思想:
设置两个节点的集合S和T,集合S中存放已找到最短路径的节点,集合T中存放当前还未找到最短路径的节点。
初始状态时,集合S中只包括源点,设为v0,然后不断从集合T中选择到源点v0路径长度最短的节点u加入到集合S中,集合S每加入一个新的节点u都要修改从源点v0到集合T中剩余节点的当前最短路径长度,集合T中各节点的新的当前路径长度值,为原来的最短路径长度值与从源点过节点u到达该节点的路径长度中的较小者。
此过程不断重复,知道集合T中的节点全部加入到集合S中为止。
模块划分:
(1)voidAdjMGraph(),以邻接矩阵存储带权有向图,其中调用了顺序表。
(2)voidAdjMGC(),创建有向图。
(3)voidDijkstra(),狄克斯特拉函数,找最短路径。
数据结构:
节点在顺序表里存储,各个边的权值在矩阵中存储。
源程序:
/*文件SepList.h*/
typedefstruct
{
DataTypelist[MaxSize];
intsize;
}SeqList;
voidListInitiate(SeqList*L)
{
L->size=0;
}
intListLength(SeqListL)
{
returnL.size;
}
intListInsert(SeqList*L,inti,DataTypex)
{
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)
{
intj;
if(L->size<=0)
{
printf("顺序表已满无法输入!
\n");
return0;
}
elseif(i<0||i>L->size-1)
{
printf("参数i不合法");
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)
{
if(i<0||i>L.size-1)
{
printf("参数不i合法!
\n");
return0;
}
else
{
*x=L.list[i];
return1;
}
}
/*文件AdjMGraph.h*/
#include"SeqList.h"
typedefstruct
{
SeqListVertices;/*存放结点的顺序表*/
intedge[MaxVertices][MaxVertices];/*存放边的邻接矩阵*/
intnumOfEdges;/*边的条数*/
}AdjMGraph;/*图的结构体定义*/
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; } G->numOfEdges=0;/*边的条数置为0*/ ListInitiate(&G->Vertices);/*顺序表初始化*/ } voidInsertVertex(AdjMGraph*G,DataTypevertex) /*在图G中插入结点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"); exit (1); } 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"); exit (1); } if(G->edge[v1][v2]==MaxWeight||v1==v2) { printf("该边不存在! \n"); exit(0); } G->edge[v1][v2]=MaxWeight; G->numOfEdges--; } voidDeleteVerten(AdjMGraph*G,intv) /*删除结点V*/ { intn=ListLength(G->Vertices),i,j; DataTypex; for(i=0;i for(j=0;j if((i==v||j==v)&&G->edge[i][j]>0&&G->edge[i][j] G->numOfEdges--;/*计算被删边数*/ for(i=v;i for(j=0;j G->edge[i][j]=G->edge[i+1][j]; for(i=0;i for(j=v;j G->edge[i][j]=G->edge[i][j+1]; ListDelete(&G->Vertices,v,&x);/*删除结点*/ } intGetFirstVex(AdjMGraphG,intv) /*在图G中寻找序号为v的结点的第一个邻接结点*/ /*如果这样的邻接结点存在,返回该邻接结点的序号;否则,返回-1*/ { intcol; if(v<0||v>G.Vertices.size) { printf("参数v1越界出错! \n"); exit (1); } for(col=0;col if(G.edge[v][col]>0&&G.edge[v][col] return-1; } intGetNextVex(AdjMGraphG,intv1,intv2) /*在图G中寻找v1结点的邻接结点v2的下一个邻接结点*/ /*如果这样的邻接结点存在,返回该邻接结点的序号;否则,返回-1*/ /*v1和v2都是相应结点的序号*/ { intcol; if(v1<0||v1>G.Vertices.size||v2<0||v2>G.Vertices.size) { printf("参数v1或v2越界出错! \n"); exit (1); } for(col=v2+1;col if(G.edge[v1][col]>0&&G.edge[v1][col] return-1; } /*文件AdjMGC.h*/ typedefstruct { introw;/*行下标*/ intcol;/*列下标*/ intweight;/*权值*/ }RowColWeight;/*边信息结构体定义*/ voidCreatGraph(AdjMGraph*G,DataTypeV[],intn,RowColWeightE[],inte) /*在图G中插入n个结点信息v和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); } /*文件Dijkstra.h*/ voidDijkstra(AdjMGraphG,intv0,intdistance[],intpath[]) /*带权图G从下标v0节点到其他节点的最短距离diatance*/ /*最短路径下标*/ { intn=G.Vertices.size; int*s=(int*)malloc(sizeof(int)*n); intminDis,i,j,u; /*初始化*/ for(i=0;i { distance[i]=G.edge[v0][i]; s[i]=0; if(i! =v0&&distance[i] elsepath[i]=-1; } s[v0]=1;//标记节点v0已从集合T加入到集合S中 /*在当前还未找到最短路径的节点集合中选取具有最短距离的节点u*/ for(i=0;i { minDis=MaxWeight; for(j=0;j if(s[j]==0&&distance[j] { u=j; minDis=distance[j]; } /*当已不存在路径时算法结束,此语句对非连通图是必须的*/ if(minDis==MaxWeight)return; s[u]=1;//标记节点u已从集合T加入到集合S中 /*修改从v0到其他节点的最短距离和最短路径*/ for(j=0;j if(s[j]==0&&G.edge[u][j] { /*节点v0经节点u到其他节点的最短距离和最短路径*/ distance[j]=distance[u]+G.edge[u][j]; path[j]=u; } } } /*测试程序*/ #include #include #include typedefcharDataType; #defineMaxSize100 #defineMaxVertices10 #defineMaxWeight10000 #include"AdjMGraph.h" #include"AdjMGC.h" #include"Dijkstra.h" voidmain() { AdjMGraphg; chara[]={'A','B','C','D','E','F'}; RowColWeightrow[]={{0,2,5},{0,3,30},{1,0,2},{1,4,8},{2,1,15},{2,5,7},{4,3,4},{5,3,10},{5,4,18}}; inti,n=6,e=9; intdistance[6],path[6]; CreatGraph(&g,a,n,row,e); Dijkstra(g,0,distance,path); printf("从节点%c到其他各节点的最短距离为: \n",g.Vertices.list[0]); for(i=0;i printf("到节点%c的最短距离为%d: \n",g.Vertices.list[i],distance[i]); printf("从节点%c到其他各节点最短路径的前一节点为: \n",g.Vertices.list[0]); for(i=0;i if(path[i]! =-1) printf("到节点%c的前一节点为: %c\n",g.Vertices.list[i],g.Vertices.list[path[i]]); } 测试结果:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 路径 上机 报告