最短路径算法源程序代码.docx
- 文档编号:10138021
- 上传时间:2023-02-08
- 格式:DOCX
- 页数:17
- 大小:18.12KB
最短路径算法源程序代码.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;i fclose(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;i for(j=0;j { if((arc[i][j] =j)) Path[i][j]=i; elsePath[i][j]=-1; } //初始化最短路径长度矩阵dist[][] for(i=0;i for(j=0;j dist[i][j]=arc[i][j]; //弗罗伊德算法 for(k=0;k for(i=0;i for(j=0;j if(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; } } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 路径 算法 源程序 代码