好久之前寫的一個東西了,
運行截圖:
對於所有的地點實現已經編號,便於後面算法的實現.
各個功能介紹:
1. 查看地圖
地圖是自己用記事本寫的, 輸出的時候直接把記事本中的內容讀取輸出即可.
另外用一個mapchart存儲二維矩陣, 代表所有地點之間的距離
2. 查看兩點之間的最短距離, 這個我是用Dijkstra寫的,其中加入了輸出路徑
代碼如下:
void Dijkstra()
{
int i,j,u,count,sum,s,v,t,min,dis[MaxSize],book[MaxSize],P[MaxSize][MaxSize];
char ch;
for(i=1; i<=Matrix.vexnum; i++)
{
printf("%d.", i);
name(i);
puts(" ");
}
printf("請輸入起點:");
scanf("%d",&s);
getchar();
printf("\n");
printf("請輸入終點:");
scanf("%d",&t);
getchar();
memset(book,0,sizeof(book));
book[s]=1;
for(v=1;v<=Matrix.vexnum;v++)
{
dis[v]=Matrix.map[s][v];
for(i=0;i<=Matrix.vexnum;i++)
P[v][i]=0;
}
for(i=1;i<Matrix.vexnum;i++)
{
min=inf;
for(j=1;j<=Matrix.vexnum;j++)
if(book[j]==0&&dis[j]<min)
{
min=dis[j];
u=j;
}
book[u]=1;
for(j=0;P[u][j]!=0;j++) ;
P[u][j]=u;
for(v=1;v<=Matrix.vexnum;v++)
{
if(dis[v]>dis[u]+Matrix.map[u][v])
{
dis[v]=dis[u]+Matrix.map[u][v];
for(j=0;P[u][j]!=0;j++)
P[v][j]=P[u][j];
}
}
}
name(s);
for(j=0;P[t][j]!=0;j++) //輸出路徑
{
printf("->");
name(P[t][j]);
}
printf("\n最短距離爲 %d",dis[j]);
printf("\n");
puts(" ");
printf("回車鍵返回...\n"); //輸入回車返回主頁面
while(scanf("%c",&ch),ch!='\n');
system("CLS");
}
3. 以當前位置生成最小生成樹, prim生成最小生成樹後輸出長度就行了
void prim() //prim算法求最小生成樹
{
int i,j,u,count,sum,s,min,dis[MaxSize],book[MaxSize];
char ch;
for(i=1; i<=Matrix.vexnum; i++) //輸出地名和編號
{
printf("%d.", i);
name(i);
puts(" ");
}
printf("請輸入所在位置: ");
scanf("%d",&s);
getchar();
memset(book, 0, sizeof(book));
book[s]=1;
count=1;
sum=0;
for(i=1;i<=Matrix.vexnum;i++)
dis[i]=Matrix.map[s][i];
while(count<Matrix.vexnum) //prim算法
{
min=inf;
for(i=1;i<=Matrix.vexnum;i++)
if(book[i]==0&&min>dis[i])
{
min=dis[i];
u=i;
}
book[u]=1;
sum+=dis[u];
count++;
for(j=1;j<=Matrix.vexnum;j++)
if(book[j]==0&&dis[j]>Matrix.map[u][j])
dis[j]=Matrix.map[u][j];
}
printf("以");
name(s);
printf("生成的最小生成樹的長度爲:%d\n",sum);
printf("回車鍵返回...\n"); //輸入回車返回主頁面
while(scanf("%c",&ch),ch!='\n');
system("CLS");
}
4.所有點之間的最短距離,這裏我用的弗洛伊德算法, 也是比較基礎的一個算法, 之後兩兩之間輸出地名和距離.
void Floyd()
{
int k,i,j;
char ch;
for(k=1;k<=Matrix.vexnum;k++) //弗洛伊德算法
for(i=1;i<=Matrix.vexnum;i++)
for(j=1;j<=Matrix.vexnum;j++)
if(Matrix.map[i][j]>Matrix.map[i][k]+Matrix.map[k][j])
Matrix.map[i][j]=Matrix.map[i][k]+Matrix.map[k][j];
for(i=1;i<=Matrix.vexnum;i++)
for(j=1;j<=Matrix.vexnum;j++)
if(i!=j)
{
printf("%d.",i); //輸出i對應的地名
name(i);
printf("到 ");
printf("%d.",j); //輸出j對應的地名
name(j);
printf("的最短距離爲 %d\n",Matrix.map[i][j]); //輸出最短距離
}
printf("回車鍵返回...\n"); //輸入回車返回主頁面
while(scanf("%c",&ch),ch!='\n');
system("CLS"); //清屏
}
所有代碼:
#include<stdio.h>
#include<windows.h>
#include<string.h>
#define MaxSize 20
const int inf=99999999; // 定義一個很大的數字認爲是無限大
typedef struct chart
{
int vexs[MaxSize]; /*頂點數組*/
int map[MaxSize][MaxSize]; /*鄰接矩陣*/
int vexnum; //頂點數
int arcnum; //邊數
}chart;
chart Matrix;
void SeeMaps(); //查看地圖函數
void Interface(); //主頁面
void Getmapchart(); //讀取矩陣
void Name(int a); // 不同的數字代表不同的地點
void Floyd(); //弗洛伊德算法求所有點之間的最短路徑
void Explain(); //程序說明
void prim(); //prim算法求最小生成樹
void Dijkstra(); //dijkstra算法求兩點之間的最短路
int main() //主函數
{
Interface();
int step; //操作選項
while(1)
{
Getmapchart(); //獲取鄰接矩陣
scanf("%d", &step);
getchar();
system("CLS"); //清屏
if(step==1)
{
SeeMaps(); //輸出地圖
Interface(); //返回主頁面
}
else if(step==2)
{
Dijkstra(); //dijkstra算法求兩點之間的最短路
Interface(); //返回主頁面
}
else if(step==3)
{
prim(); //求最小生成樹
Interface(); //返回主頁面
}
else if(step==4)
{
Floyd(); //弗洛伊德算法
Interface(); //返回主頁面
}
else if(step==5)
{
Explain(); //調用程序說明的函數
Interface(); //返回主頁面
}
else if(step==6) //程序結束
break;
else
{
printf("輸入錯誤!");
char ch;
while(scanf("%c",&ch),ch!='\n');
system("CLS"); //清屏
Interface();
}
}
return 0;
}
void Getmapchart() //讀取矩陣
{
FILE *fp;
int i,j;
fp=fopen("mapchart.txt","r"); //打開矩陣的文件
Matrix.vexnum=15; //頂點數爲15
Matrix.arcnum=24; //邊的數目爲24
for(i=1;i<=Matrix.vexnum;i++) //循環讀取
for(j=1;j<=Matrix.vexnum;j++)
{
fscanf(fp,"%d",&Matrix.map[i][j]); //將在文件中獲取到的數字賦給矩陣
if(i!=j&&Matrix.map[i][j]==0) //如果兩個地點之間沒有路可以到達,
Matrix.map[i][j]=inf; //認爲它們之間的距離爲無限大
}
fclose(fp); //關閉文件
}
void Interface() //主頁面
{
printf("1.查看地圖\n");
printf("2.當前位置到指定位置的最短路徑\n");
printf("3.以當前位置生成最小生成樹\n");
printf("4.所有點之間的最短距離\n");
printf("5.說明\n");
printf("6.退出\n");
return ;
}
void SeeMaps() //查看地圖
{
FILE *fp;
char ch;
fp=fopen("map.txt","r"); //打開保存地圖的文件
for(;(ch=fgetc(fp))!=EOF; ) //輸出保存在文件中地圖
putchar(ch);
puts(" ");
printf("回車鍵返回...\n"); //輸入回車返回主頁面
while(scanf("%c",&ch),ch!='\n');
system("CLS"); //清屏
fclose(fp); //關閉文件
return ;
}
void name(int a) //調用函數可以輸出相應的數字所對應的地名
{
switch(a)
{
case 1:printf("北門");break;
case 2:printf("西門");break;
case 3:printf("南門");break;
case 4:printf("東門");break;
case 5:printf("陶瓷館");break;
case 6:printf("近代歷史館");break;
case 7:printf("玉器館");break;
case 8:printf("猿人館");break;
case 9:printf("廁所");break;
case 10:printf("璽印館");break;
case 11:printf("雕塑館");break;
case 12:printf("繪畫館");break;
case 13:printf("傳統傢俱館");break;
case 14:printf("休息區");break;
case 15:printf("中央噴水池");break;
}
}
void Floyd()
{
int k,i,j;
char ch;
for(k=1;k<=Matrix.vexnum;k++) //弗洛伊德算法
for(i=1;i<=Matrix.vexnum;i++)
for(j=1;j<=Matrix.vexnum;j++)
if(Matrix.map[i][j]>Matrix.map[i][k]+Matrix.map[k][j])
Matrix.map[i][j]=Matrix.map[i][k]+Matrix.map[k][j];
for(i=1;i<=Matrix.vexnum;i++)
for(j=1;j<=Matrix.vexnum;j++)
if(i!=j)
{
printf("%d.",i); //輸出i對應的地名
name(i);
printf("到 ");
printf("%d.",j); //輸出j對應的地名
name(j);
printf("的最短距離爲 %d\n",Matrix.map[i][j]); //輸出最短距離
}
printf("回車鍵返回...\n"); //輸入回車返回主頁面
while(scanf("%c",&ch),ch!='\n');
system("CLS"); //清屏
}
void Explain() //程序說明
{
char ch;
printf("本程序用於實現博物館導遊系統,\n");
printf("操作1可以查看地圖\n");
printf("操作2可以查看兩個點之間的最短距離及路徑\n");
printf("操作3可以查看以當前位置生成最小生成樹的長度\n");
printf("操作4可以任意兩個點之間的最短距離\n");
printf("回車鍵返回...\n"); //輸入回車返回主頁面
while(scanf("%c",&ch),ch!='\n');
system("CLS"); //清屏
}
void prim() //prim算法求最小生成樹
{
int i,j,u,count,sum,s,min,dis[MaxSize],book[MaxSize];
char ch;
for(i=1; i<=Matrix.vexnum; i++) //輸出地名和編號
{
printf("%d.", i);
name(i);
puts(" ");
}
printf("請輸入所在位置: ");
scanf("%d",&s);
getchar();
memset(book, 0, sizeof(book));
book[s]=1;
count=1;
sum=0;
for(i=1;i<=Matrix.vexnum;i++)
dis[i]=Matrix.map[s][i];
while(count<Matrix.vexnum) //prim算法
{
min=inf;
for(i=1;i<=Matrix.vexnum;i++)
if(book[i]==0&&min>dis[i])
{
min=dis[i];
u=i;
}
book[u]=1;
sum+=dis[u];
count++;
for(j=1;j<=Matrix.vexnum;j++)
if(book[j]==0&&dis[j]>Matrix.map[u][j])
dis[j]=Matrix.map[u][j];
}
printf("以");
name(s);
printf("生成的最小生成樹的長度爲:%d\n",sum);
printf("回車鍵返回...\n"); //輸入回車返回主頁面
while(scanf("%c",&ch),ch!='\n');
system("CLS");
}
void Dijkstra()
{
int i,j,u,count,sum,s,v,t,min,dis[MaxSize],book[MaxSize],P[MaxSize][MaxSize];
char ch;
for(i=1; i<=Matrix.vexnum; i++)
{
printf("%d.", i);
name(i);
puts(" ");
}
printf("請輸入起點:");
scanf("%d",&s);
getchar();
printf("\n");
printf("請輸入終點:");
scanf("%d",&t);
getchar();
memset(book,0,sizeof(book));
book[s]=1;
for(v=1;v<=Matrix.vexnum;v++)
{
dis[v]=Matrix.map[s][v];
for(i=0;i<=Matrix.vexnum;i++)
P[v][i]=0;
}
for(i=1;i<Matrix.vexnum;i++)
{
min=inf;
for(j=1;j<=Matrix.vexnum;j++)
if(book[j]==0&&dis[j]<min)
{
min=dis[j];
u=j;
}
book[u]=1;
for(j=0;P[u][j]!=0;j++) ;
P[u][j]=u;
for(v=1;v<=Matrix.vexnum;v++)
{
if(dis[v]>dis[u]+Matrix.map[u][v])
{
dis[v]=dis[u]+Matrix.map[u][v];
for(j=0;P[u][j]!=0;j++)
P[v][j]=P[u][j];
}
}
}
name(s);
for(j=0;P[t][j]!=0;j++) //輸出路徑
{
printf("->");
name(P[t][j]);
}
printf("\n最短距離爲 %d",dis[j]);
printf("\n");
puts(" ");
printf("回車鍵返回...\n"); //輸入回車返回主頁面
while(scanf("%c",&ch),ch!='\n');
system("CLS");
}