狄克斯特拉算法.docx
《狄克斯特拉算法.docx》由会员分享,可在线阅读,更多相关《狄克斯特拉算法.docx(8页珍藏版)》请在冰豆网上搜索。
狄克斯特拉算法
报告题目:
狄克斯特拉算法的实现
问题描述:
带权图中从一个结点到另一个结点可能存在着多条路径,带权路径长度值最小的那条路径称为最短路径,狄克斯特拉提出了一个按路径长度递增的顺序逐步产生最短路径的构造算法。
用狄克斯特拉算法编一个程序求带权图的最短路径。
如下图是一个有向带权图及其邻接矩阵。
该带权图从结点A到结点D有三条路径,分别为路径(A,D),其带权路径长度为30;路径(A,C,F,D),其带权路径长度为22;路径(A,C,B,E,D),其带权路径长度为32。
路径(A,C,F,D)称为最短路径,其带权路径长度22称为最短距离。
基本要求:
1.测试数据由用户在程序中给出。
2.在狄克斯特拉函数设计中把函数设计成一个循环迭代过程。
3.输入边信息数据时,以其在邻接矩阵的(行下标,列下标,权值)形式输入。
4.要求输出固定结点到各结点的最短距离和最短路径的前一结点。
测试数据:
结点:
a[]={'A','B','C','D','E','F'};
边:
rcw[]={{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).文件“SeqList.h”,用于下文件“AMGraph.h”,其中包括顺序表的初始化、求当前数据元素个数、插入、删除、取数据元素操作;
(2).文件“AMGraph.h”,有初始化、插入结点、插入边、删除边、删除结点、寻找邻接结点和邻接结点的下一邻接结点的操作;
(3).文件“AMGraphC.h”,用于图的创建;
(4).文件“Dijkstra.h”,狄克斯特拉函数的设计;
(5).文件“Main.c”,输出结点A到其他结点的最短距离和最短路径的前一结点。
数据结构:
1)线性表数据结构:
typedefstruct
{
DataTypelist[MaxSize];
intsize;
}SeqList;
2)图的数据结构:
typedefstruct
{
SeqListVertices; /*存放结点的顺序表*/
intedge[MaxVertices][MaxVertices]; /*存放边的邻接矩阵*/
intnumOfEdges; /*边的条数*/
}AMGraph; /*图的结构体定义*/
3)边的数据结构
typedefstruct
{
introw; /*行下标*/
intcol; /*列下标*/
intweight; /*权值*/
}RowColWeight; /*边信息结构体定义*/
源程序:
文件“SeqList.h”
/*定义结构体*/
typedefstruct
{
DataTypelist[MaxSize];
intsize;
}SeqList;
/*初始化*/
voidListInitiate(SeqList*L)
{
L->size=0;
}
/*求当前数据元素个数*/
intListLength(SeqList L)
{
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; /*插入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]; /*保存删除的元素到x中*/
/*依次前移*/
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个数据元素存于x中,成功返回,失败返回*/
{
if(i<0||i>L.size-1)
{
printf("参数i不合法!
\n");
return0;
}
else
{
*x=L.list[i];
return1;
}
}
文件”AMGraph.h”
#include"SeqList.h" /*包含顺序表头文件*/
typedefstruct
{
SeqListVertices; /*存放结点的顺序表*/
intedge[MaxVertices][MaxVertices]; /*存放边的邻接矩阵*/
intnumOfEdges; /*边的条数*/
}AMGraph; /*图的结构体定义*/
voidInitiate(AMGraph*G,intn) /*初始化*/
{
inti,j;
for(i=0;ifor(j=0;j{
if(i==j)G->edge[i][j]=0;
elseG->edge[i][j]=MaxWeight;
}
G->numOfEdges=0; /*边的条数置为0*/
ListInitiate(&G->Vertices); /*顺序表初始化*/
}
voidInsertVertex(AMGraph*G,DataTypevertex)
/*在图G中插入结点vertex*/
{
ListInsert(&G->Vertices,G->Vertices.size,vertex);
/*顺序表尾插入*/
}
voidInsertEdge(AMGraph*G,intv1,intv2,intweight)
/*在图G中插入边,边的权为weight*/
{
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(AMGraph*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--;
}
voidDeleteVertex(AMGraph*G,intv)
/*删除结点v*/
{
intn=ListLength(G->Vertices),i,j;
DataTypex;
for(i=0;ifor(j=0;jif((i==v||j==v)&&G->edge[i][j]>0&&G->edge[i][j]G->numOfEdges--; /*计算被删除边*/
for(i=v;ifor(j=0;jG->edge[i][j]=G->edge[i+1][j];
for(i=0;ifor(j=v;jG->edge[i][j]=G->edge[i][j+1];
ListDelete(&G->Vertices,v,&x); /*删除结点v*/
}
intGetFirstVex(AMGraphG,intv)
/*在图G中寻找序号为v的结点的第一个邻接结点*/
/*如果这样的邻接结点存在,返回该邻接结点的序号;否则,返回-1*/
{
intcol;
if(v<0||v>G.Vertices.size)
{
printf("参数v1越界出错!
\n");
exit
(1);
}
for(col=0;colif(G.edge[v][col]>0&&G.edge[v][col]return-1;
}
intGetNextVex(AMGraphG,intv1,intv2)
/*在图G中寻找V1结点的邻接结点v2的下一个邻接结点*/
/*如果这样的邻接结点存在,返回该邻接结点的序号;否则,返回-1*/
/*v1和v2都是相应结点的序号*/
{
intcol;
if(v1<0||v1>G.Vertices.size||v2<0||v2>G.Vertices.size)