數據結構課程設計 : 博物館導航系統

好久之前寫的一個東西了,

運行截圖:

對於所有的地點實現已經編號,便於後面算法的實現.

各個功能介紹:

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");
} 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章