数据结构课程设计 : 博物馆导航系统

好久之前写的一个东西了,

运行截图:

对于所有的地点实现已经编号,便于后面算法的实现.

各个功能介绍:

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

 

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
收藏夹和购物车系统的实现  收藏夹子系统 (1) 【收藏指定图书】能收藏一本图书,并记录收藏日期(某年某月某日,如2016-12-12。所有日期都采用人工定义方式输入,不取机器日期)。图书的信息包括图书号(是唯一的)、书名、作者、出版社、出版日期、价格。 (2) 【查询指定图书】能按照图书号查询显示收藏夹中图书的相关信息(也可以扩展功能为按照书名、作者、出版社、出版日期、指定价格大小范围查询显示收藏夹中图书的相关信息)。 (3) 【按日期显示所有图书】能按照收藏日期的先后显示输出所收藏的所有图书的相关信息。 (4) 【移出收藏夹】可以把不想收藏的某一本指定图书号的图书直接移出收藏夹。 (5) 【加入购物车】将收藏夹中的某一本指定图书号的图书加入到购物车。 (6) 【按价格显示所有图书】能按照价格的大小显示输出收藏夹中的所有图书的相关信息。  购物车子系统 (1) 【直接加入购物车】把准备购买的一本图书直接加入购物车,同时记录加入购物车的日期。图书的信息包括图书号(是唯一的)、书名、作者、出版社、出版日期、价格、购买数量、购买金额(自动计算)。 (2) 【查询指定图书】能按照图书号查询显示购物车中准备购买的图书的相关信息(也可以扩展功能为按照书名、作者、出版社、出版日期、指定价格大小范围查询显示购物车中图书的相关信息)。 (3) 【修改购买数量】可以修改购物车中准备购买的某一本指定图书号的图书的数量,同时自动计算修改购买金额(购买金额=购买数量*价格)。 (4) 【删除指定图书并移到收藏夹】把购物车中的某一本指定图书号的图书删除并移到收藏夹。 (5) 【直接删除指定图书】可以把不想购买的某一本指定图书号的图书从购物车中删除。 (6) 【按图书号显示所有图书】把购物车中所有图书按照图书号列出每一本图书的图书号、书名、作者、出版社、出版日期、价格、购买数量、购买金额,最后列出总共有多少本图书、总金额是多少。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张宜强

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值