最短路径算法源程序代码

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

// 最大结 // 节点 // 若节点间 #include < stdio .h>
#include < conio.h>
#include < string .h> #define
JiedianNum 6 点数
#define NameLenght 3 名字长度
#define Infinity 10000 没有路径距离设定为 Infinity char
*JiedianNameFile = "jiedianname.txt" ;
// 图的顶点 -- 节点名
char *JiedianPathFile = "jiedianpath.txt" ; // 边 -- 节点间的连接关系
char *MinPathDataFile ="minpath.txt" ;
// 最短路径数据
/******************************************************* /* 从文件中读入结点数据
*/
/* 函数参数:
*/
/* char jiedian[][]: 存放节点名的数组
*/
/* int *NodNum: 指针变量,指向存放节点个
数的变量*/
/* 输入数据:文本数据文件:JiedianNameFile
*/
/* 文件数据格式:
*/
/* < 节点个数>
*/
/* < 节点名>
*/
/* 输出数据:指从该函数中带回到调用函数的数据,包括:*/
/* jiedian[][]-- 节点名称
*/
/* NodeNum-- 节点名的个数
*/
/* 返回值:数据读入是否成功的标志
*/
/* 0-- 失败1-- 成功
*/
/******************************************************* int InputJiedianNode( char jiedian[][NameLenght], int *NodeNum )
{int i,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;i< n;i++ ) fscanf(fp, "%s" ,jiedian[i]);
fclose(fp);
*NodeNum =n;
return (1);
}
I******************************************************* /* 从文件中读入最短路径数据*/
/* 函数参数:
*/
/* int dist[][]: 节点间最短路径的值
*/
/* int Path[][]: 节点间最短路径结点数据
*/
/* int *NodNum: 指针变量,表示读入数据的
多少*/
/* 输入数据:数据文件:MinPathDataFile
*/
/* 文件数据格式:二进制数据,数据存放顺序:*/
/* < 节点个数n><n*n 个最短路径
值><n*n 个结点值> */
/* 输出数据:指从该函数中带回到调用函数的数据,包括:*/
/* jiedian[][]
*/
/* Path[][]
*/
*/
/* 返回值:数据读入是否成功的标志
*/
/* 0-- 失败1-- 成功
*/
/******************************************************* int InputMinPath( int dist[][JiedianNum], int
Path[][JiedianNum], int *NodeNum)
{int n;
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);
}
/******************************************************* /* 查找节点名
*/
/* 函数参数:
*/
/* char str[][]: 存放节点名的数组
*/
/* int n :str 中数据的行数,即节点名的个
数*/
/* char *p: 指针变量,表示需要查找的节点名
*/
/* 输入数据:全部函数参数均为输入数据
*/
/* 输出数据:返回值作为函数的输出数据
*/
/* 查找成功:被查找的节点名在数组str 中的序号*/ /* 查找失败:-1,表示被查找的节点名未
出现在数组中*/
/******************************************************* int search( char str[][NameLenght], int n,char
*p)
{int i=0;
while(i< n)
{ if (!strcmp(str[i],p)) return (i); i++;
} return (- 1); }
I*******************************************************
/*
*/
/* 函数参数:
计算节点间最短路径< 无>
*/
/* 输入数据:文本数据文件:JiedianNameFile
*/ /* */ /* */ /* */ /*
文件数据格式:
< 节点个数>
< 节点名>
文本数据文件:JiedianPathFile
*/ /*
文件数据格式:
*/
/* < 边数>
*/
/* < 结点名>< 节点名>< 边值> */
/* 输出数据:数据文件:MinPathDataFile
*/
/* 文件数据格式:二进制数据,数据存放顺序:*/ /* < 结点个数n><n*n 个最短路径
值><n*n 个结点值> */
/* 返回值:< 无>
*/
/* 说明:文本数据文件中数据间用空格或换行符格开*/
/******************************************************* void shorttestpath()
{
int i,j,k,NodeNum,EgeNum,val;
int arc[JiedianNum][JiedianNum];
// 权值矩阵
char jiedian[JiedianNum][NameLenght];
// 结点
int dist[JiedianNum][JiedianNum]; // 最短路径长度矩阵
int Path[JiedianNum][JiedianNum];
// 最短路径矩阵
char
jiedian1[NameLenght],jiedian2[NameLenght]
J
FILE *fp;
/* ------------------------------
-------------------- */
/* 算法步骤:
*/
/* 1、读入结点数据
*/
/* 2、邻接矩阵初始化:所有元素赋
Infinity ,*/
/* 对角线元素赋0 */
/* 3、读入结点间边的数据,转换为邻接
矩阵的数据*/
/* 4、路径矩阵初始化,若
arc[i][j]<Infinity ,*/
/* 则:at[i][j]=i 否则:
Path[i][j]=-1 */
/* 5、计算最短路径
*/
/* 6、保存最小路径数据
*/
/* ------------------------------
-------------------- */
// -------- 初始化邻接矩阵
if (!InputJiedianNode(jiedian, & NodeNum)) return ;
else
{
for (i= 0;i< NodeNum;i ++)
{
for (j =0;j< NodeNum;j ++)
if(i== j) arc[i][j] =0; else arc[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< EgeNum;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;i< NodeNum;i ++)
for (j = 0;j < NodeNum;j ++)
{
if ((arc[i][j] < Infinity) && (i!= j))
Path[i][j] =i;
else Path[i][j] =- 1;
}
// 初始化最短路径长度矩阵dist[][]
for (i= 0;i< NodeNum;i ++ )
for (j = 0;j< NodeNum;j ++)
dist[i][j] =arc[i][j];
// 弗罗伊德算法
for (k=0;k< NodeNum;k ++)
for (i= 0;i< NodeNum;i ++ )
for (j = 0;j < NodeNum;j ++)
if (dist[i][k] +dist[k][j] < dist[i][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,f p);
fclose(fp);
return ;
}
/******************************************************* /* 求一个节点到其它节点的最短路径*/
/* 函数参数:< 无>
*/
/* 输入数据:文本数据文件:JiedianNameFile */
/* 数据文件:MinPathDataFile
*/
*/
/* 输出数据:
*/
/* 指定节点到其它所有节点的最短路径值
和路径*/
/* (屏幕显式)
*/
/* 返回值:< 无>
*/
/******************************************************* void One_To_Other_Path()
{int i,j,k,NodeNum,StartNode;
char jiedian[JiedianNum][NameLenght];
// 结点
int dist[JiedianNum][JiedianNum];
// 最短路径长度矩阵
int Path[JiedianNum][JiedianNum];
// 最短路径矩阵
int top,PathStack[JiedianNum]; char jiedian1[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< NodeNum;i ++ )
{
j=i;
top = StartNode =0;
if (i== k) continue ;
printf( "起始节点和终止节
点: %s==>%s\n" ,jiedian[k],jiedian[i]);
printf( "最短路径: %d
km\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
*/
/* 起点节点名,终点节点名,从键盘输入*/
/* 输出数据:
*/
/* 起点节点到终点节点的最短路径值和路
径*/
/* (屏幕显式)
*/
/* 返回值:< 无>
*/
/******************************************************* void One_To_One_Path()
{int i,j,k,NodeNum,StartNode,EndNode;
char jiedian[JiedianNum][NameLenght];
// 结点
int dist[JiedianNum][JiedianNum];
// 最短路径长度矩阵
int Path[JiedianNum][JiedianNum];
// 最短路径矩阵
int top,PathStack[JiedianNum];
char
jiedian1[NameLenght],jiedian2[NameLenght]
J
FILE *fp;
/* ------------------------------
-------------------- */
/* 算法步骤:
*/
/* 1、输入结点数据
*/
/* 2、输入最小路径数据
*/
/* 3、输入起点节点和终点节点名称,并
确定其正确性*/
/* 方法:调用查找函数,若返回值>=0 则正确*/
/* 4、求起点节点到终点节点的最短路径*/
/* 方法:根据两节点的序号i,j在dist
数组中获得/*
中结点间路径/*
并放入栈中,/* */
最短路径值。

根据Path 数组*/
数据的关系求的其结点序列*/
然后依次输出栈数据。

*/
/* ------------------------------
-------------------- */
// 从文件中读入结点数据
if(!InputJiedianNode(jiedian, & Nod eNum)) { 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: %d
km\n" ,jiedian1,jiedian2,dist[StartNode][EndN ode]);
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)
,jiedian[PathStack[--top]]);
1*1
); printf( "==>%s" } getch(); return ;
} int nemu()
{
int num;
printf( "\n ************* 最短路径路由 程序 ******************\n);"
printf( " *%15c1--- 全部节
点%22c\n" ,' ', '*');
printf( " *%15c2--- 从一个节点到其他 所有节点 %6c\n" ,' ','*');
printf( " *%15c3--- 从一个节点到另一 个节点 %8c\n" ,' ', '*');
printf( " *%15c4---退出 %26c\n",'', printf( "
********************************************
printf( "%15c 请选择 1,2,3,4:"'');
do{
scanf( "%d" ,&num);
}while(num<1 ||num>4); return (num);
}
void main()
{
while(1)
{
switch (nemu())
{
case 1:
shorttestpath();
break ;
case 2:
One_To_Other_Path();
break ;
case 3:
One_To_One_Path();
break ;
case 4:
return ;
}
}
}。

相关文档
最新文档