最短路径算法源程序代码.docx
《最短路径算法源程序代码.docx》由会员分享,可在线阅读,更多相关《最短路径算法源程序代码.docx(17页珍藏版)》请在冰豆网上搜索。
最短路径算法源程序代码
#include
#include
#include
#defineJiedianNum6//最大结点数
#defineNameLenght3//节点名字长度
#defineInfinity10000//若节点间没有路径距离设定为Infinity
char*JiedianNameFile="jiedianname.txt";//图的顶点--节点名
char*JiedianPathFile="jiedianpath.txt";//边--节点间的连接关系
char*MinPathDataFile="minpath.txt";//最短路径数据
/********************************************************/
/*从文件中读入结点数据*/
/*函数参数:
*/
/*charjiedian[][]:
存放节点名的数组*/
/*int*NodNum:
指针变量,指向存放节点个数的变量*/
/*输入数据:
文本数据文件:
JiedianNameFile*/
/*文件数据格式:
*/
/*<节点个数>*/
/*<节点名>*/
/*输出数据:
指从该函数中带回到调用函数的数据,包括:
*/
/*jiedian[][]--节点名称*/
/*NodeNum--节点名的个数*/
/*返回值:
数据读入是否成功的标志*/
/*0--失败1--成功*/
/********************************************************/
intInputJiedianNode(charjiedian[][NameLenght],int*NodeNum)
{inti,n;
FILE*fp;
if(!
(fp=fopen(JiedianNameFile,"r")))
{printf("节点数据文件不存在\n");
getch();
return(0);
}
fscanf(fp,"%d",&n);
if(!
n)
{printf("文件中无节点数据!
\n");
getch();
return(0);
}
for(i=0;ifclose(fp);
*NodeNum=n;
return
(1);
}
/********************************************************/
/*从文件中读入最短路径数据*/
/*函数参数:
*/
/*intdist[][]:
节点间最短路径的值*/
/*intPath[][]:
节点间最短路径结点数据*/
/*int*NodNum:
指针变量,表示读入数据的多少*/
/*输入数据:
数据文件:
MinPathDataFile*/
/*文件数据格式:
二进制数据,数据存放顺序:
*/
/*<节点个数n>*/
/*输出数据:
指从该函数中带回到调用函数的数据,包括:
*/
/*jiedian[][]*/
/*Path[][]*/
/*NodeNum*/
/*返回值:
数据读入是否成功的标志*/
/*0--失败1--成功*/
/********************************************************/
intInputMinPath(intdist[][JiedianNum],intPath[][JiedianNum],int*NodeNum)
{intn;
FILE*fp;
if(!
(fp=fopen(MinPathDataFile,"rb")))
{printf("最小路径数据文件不存在!
\n");
getch();
return(0);
}
fread(&n,sizeof(int),1,fp);
fread(dist,sizeof(int),n*n,fp);
fread(Path,sizeof(int),n*n,fp);
fclose(fp);
*NodeNum=n;
return
(1);
}
/********************************************************/
/*查找节点名*/
/*函数参数:
*/
/*charstr[][]:
存放节点名的数组*/
/*intn:
str中数据的行数,即节点名的个数*/
/*char*p:
指针变量,表示需要查找的节点名*/
/*输入数据:
全部函数参数均为输入数据*/
/*输出数据:
返回值作为函数的输出数据*/
/*查找成功:
被查找的节点名在数组str中的序号*/
/*查找失败:
-1,表示被查找的节点名未出现在数组中*/
/********************************************************/
intsearch(charstr[][NameLenght],intn,char*p)
{inti=0;
while(i{if(!
strcmp(str[i],p))return(i);
i++;
}
return(-1);
}
/********************************************************/
/*计算节点间最短路径*/
/*函数参数:
<无>*/
/*输入数据:
文本数据文件:
JiedianNameFile*/
/*文件数据格式:
*/
/*<节点个数>*/
/*<节点名>*/
/*文本数据文件:
JiedianPathFile*/
/*文件数据格式:
*/
/*<边数>*/
/*<结点名><节点名><边值>*/
/*输出数据:
数据文件:
MinPathDataFile*/
/*文件数据格式:
二进制数据,数据存放顺序:
*/
/*<结点个数n>*/
/*返回值:
<无>*/
/*说明:
文本数据文件中数据间用空格或换行符格开*/
/********************************************************/
voidshorttestpath()
{
inti,j,k,NodeNum,EgeNum,val;
intarc[JiedianNum][JiedianNum];//权值矩阵
charjiedian[JiedianNum][NameLenght];//结点
intdist[JiedianNum][JiedianNum];//最短路径长度矩阵
intPath[JiedianNum][JiedianNum];//最短路径矩阵
charjiedian1[NameLenght],jiedian2[NameLenght];
FILE*fp;
/*----------------------------------------------------*/
/*算法步骤:
*/
/*1、读入结点数据*/
/*2、邻接矩阵初始化:
所有元素赋Infinity,*/
/*对角线元素赋0*/
/*3、读入结点间边的数据,转换为邻接矩阵的数据*/
/*4、路径矩阵初始化,若arc[i][j]/*则:
at[i][j]=i否则:
Path[i][j]=-1*/
/*5、计算最短路径*/
/*6、保存最小路径数据*/
/*----------------------------------------------------*/
//--------初始化邻接矩阵------------
if(!
InputJiedianNode(jiedian,&NodeNum))return;
else
{
for(i=0;i{
for(j=0;j{
if(i==j)arc[i][j]=0;
elsearc[i][j]=Infinity;
}
printf("%s\n",jiedian[i]);
}
}
//-----读入结点间边的数据-------
if(!
(fp=fopen(JiedianPathFile,"r")))
{
printf("结点间边的数据文件不存在!
!
!
\n");
getch();
return;
}
fscanf(fp,"%d",&EgeNum);
if(!
EgeNum)
{
printf("文件中无结点间边的数据!
!
!
\n");
getch();
return;
}
for(k=0;k{
fscanf(fp,"%s",jiedian1);
fscanf(fp,"%s",jiedian2);
fscanf(fp,"%d",&val);
i=search(jiedian,NodeNum,jiedian1);
j=search(jiedian,NodeNum,jiedian2);
arc[i][j]=arc[j][i]=val;
}
fclose(fp);
//---------路径矩阵初始化-------------
for(i=0;ifor(j=0;j{
if((arc[i][j]=j))
Path[i][j]=i;
elsePath[i][j]=-1;
}
//初始化最短路径长度矩阵dist[][]
for(i=0;ifor(j=0;jdist[i][j]=arc[i][j];
//弗罗伊德算法
for(k=0;kfor(i=0;ifor(j=0;jif(dist[i][k]+dist[k][j]{
dist[i][j]=dist[i][k]+dist[k][j];
Path[i][j]=Path[k][j];
}
//---------保存城市间最短路径的信息-----------------
if(!
(fp=fopen(MinPathDataFile,"wb")))
{
printf("打不开文件%s!
!
!
\n",MinPathDataFile);
getch();
return;
}
fwrite(&NodeNum,sizeof(int),1,fp);
fwrite(dist,sizeof(int),NodeNum*NodeNum,fp);
fwrite(Path,sizeof(int),NodeNum*NodeNum,fp);
fclose(fp);
return;
}
/********************************************************/
/*求一个节点到其它节点的最短路径*/
/*函数参数:
<无>*/
/*输入数据:
文本数据文件:
JiedianNameFile*/
/*数据文件:
MinPathDataFile*/
/*指定节点名,从键盘输入*/
/*输出数据:
*/
/*指定节点到其它所有节点的最短路径值和路径*/
/*(屏幕显式)*/
/*返回值:
<无>*/
/********************************************************/
voidOne_To_Other_Path()
{inti,j,k,NodeNum,StartNode;
charjiedian[JiedianNum][NameLenght];//结点
intdist[JiedianNum][JiedianNum];//最短路径长度矩阵
intPath[JiedianNum][JiedianNum];//最短路径矩阵
inttop,PathStack[JiedianNum];
charjiedian1[NameLenght];
FILE*fp;
/*-----------------------------------------------------*/
/*算法步骤:
*/
/*1、输入结点数据*/
/*2、输入最小路径数据*/
/*3、输入起点节点名称,并确定其正确性*/
/*方法:
调用查找函数,若返回值>=0则正确*/
/*4、依次求起点节点到其它节点的最短路径*/
/*方法:
根据两节点的序号i,j在dist数组中获得*/
/*最短路径值。
根据Path数组中结点间路径*/
/*数据的关系求的其结点序列并放入栈中,*/
/*然后依次输出栈数据。
*/
/*----------------------------------------------------*/
//从文件中读入结点数据
if(!
InputJiedianNode(jiedian,&NodeNum))
{
printf("读取节点文件失败%s!
!
!
\n",JiedianNameFile);
getch();
return;
}
//从文件中读入最小路径数据
if(!
InputMinPath(dist,Path,&NodeNum))
{
printf("读取最短路径文件失败%s!
!
!
\n",MinPathDataFile);
getch();
return;
}
//输入起点节点名
printf("请输入节点名称:
");
scanf("%s",&jiedian1);
k=search(jiedian,NodeNum,jiedian1);
if(k<0)
{
printf("错误的节点名称%s!
!
!
\n",jiedian1);
getch();
return;
}
//获得路径结点关系,并依次入栈
for(i=0;i{
j=i;
top=StartNode=0;
if(i==k)continue;
printf("起始节点和终止节点:
%s==>%s\n",jiedian[k],jiedian[i]);
printf("最短路径:
%dkm\n",dist[k][i]);
PathStack[top++]=j;
while(Path[k][j]!
=k)
{
PathStack[top++]=Path[k][j];
j=Path[k][j];
}
//依次输出最小路径上的结点
printf("最短路经:
\n%s",jiedian[k]);
while(top)
{
printf("==>%s",jiedian[PathStack[--top]]);
}
getch();
printf("\n\n");
}
}
/********************************************************/
/*求一个节点到另一个节点的最短路径*/
/*函数参数:
<无>*/
/*输入数据:
文本数据文件:
JiedianNameFile*/
/*数据文件:
MinPathDataFile*/
/*起点节点名,终点节点名,从键盘输入*/
/*输出数据:
*/
/*起点节点到终点节点的最短路径值和路径*/
/*(屏幕显式)*/
/*返回值:
<无>*/
/********************************************************/
voidOne_To_One_Path()
{inti,j,k,NodeNum,StartNode,EndNode;
charjiedian[JiedianNum][NameLenght];//结点
intdist[JiedianNum][JiedianNum];//最短路径长度矩阵
intPath[JiedianNum][JiedianNum];//最短路径矩阵
inttop,PathStack[JiedianNum];
charjiedian1[NameLenght],jiedian2[NameLenght];
FILE*fp;
/*----------------------------------------------------*/
/*算法步骤:
*/
/*1、输入结点数据*/
/*2、输入最小路径数据*/
/*3、输入起点节点和终点节点名称,并确定其正确性*/
/*方法:
调用查找函数,若返回值>=0则正确*/
/*4、求起点节点到终点节点的最短路径*/
/*方法:
根据两节点的序号i,j在dist数组中获得*/
/*最短路径值。
根据Path数组中结点间路径*/
/*数据的关系求的其结点序列并放入栈中,*/
/*然后依次输出栈数据。
*/
/*----------------------------------------------------*/
//从文件中读入结点数据
if(!
InputJiedianNode(jiedian,&NodeNum))
{
printf("读取节点文件失败%s!
!
!
\n",JiedianNameFile);
getch();
return;
}
//从文件中读入最小路径数据
if(!
InputMinPath(dist,Path,&NodeNum))
{
printf("读取最短路径文件失败%s!
!
!
\n",MinPathDataFile);
getch();
return;
}
//用户输入起点节点和终点节点
printf("请输入起始节点名称:
");
scanf("%s",jiedian1);
printf("请输入终止节点名称:
");
scanf("%s",jiedian2);
//调用查找函数,
StartNode=search(jiedian,NodeNum,jiedian1);
EndNode=search(jiedian,NodeNum,jiedian2);
if(StartNode<0||EndNode<0)//检测节点名正确性
{
printf("错误的节点名称!
!
!
\n");
getch();
return;
}
//获得结点关系,并依次进栈,输出之
printf("距离为%s==>%s:
%dkm\n",jiedian1,jiedian2,dist[StartNode][EndNode]);
i=StartNode;
j=EndNode;
top=0;
PathStack[top++]=j;//终点节点入栈
while(Path[i][j]!
=i)
{
PathStack[top++]=Path[i][j];//最短路径上其它结点入栈
j=Path[i][j];
}
printf("最短路径:
\n");
printf("%s",jiedian1);
while(top)
{
printf("==>%s",jiedian[PathStack[--top]]);
}
getch();
return;
}
intnemu()
{
intnum;
printf("\n*************最短路径路由程序******************\n");
printf("*%15c1---全部节点%22c\n",'','*');
printf("*%15c2---从一个节点到其他所有节点%6c\n",'','*');
printf("*%15c3---从一个节点到另一个节点%8c\n",'','*');
printf("*%15c4---退出%26c\n",'','*');
printf("**************************************************\n");
printf("%15c请选择1,2,3,4:
",'');
do{
scanf("%d",&num);
}while(num<1||num>4);
return(num);
}
voidmain()
{
while
(1)
{
switch(nemu())
{
case1:
shorttestpath();
break;
case2:
One_To_Other_Path();
break;
case3:
One_To_One_Path();
break;
case4:
return;
}
}
}