数据结构课程设计 校园导航系统

425 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

校园导航系统

【问题描述】

当对校园参观时,会遇到这样的问题:如果从校园的某个位置出发,参观到校园中的所有景点,怎样设计路线,使参观者既能参观所有景点又使走的路程最少。

【数据描述】

定义一个邻接矩阵存储结构,用来存储点和边的信息。 定义一个辅助数组closedge,该数组包含两个分量,lowcost记录从U到V-U具有最小代价的边,adjvex记录改边依附于U中的顶点。

typedef char ElemType;
typedef struct {
	ElemType vexs[max];
	int arcs[max][max];
	int vexnum,arcnum;
}MGraph; 
struct {
	ElemType adjvex;
	int lowcost;
}closedge[max];

【算法思想】

(1)已知校园中各景点和路径的权重,使参观者既能参观所有景点又使走的路程最少。即求最小生成树,使得路径保持连通且经过所有边权值之和最小。

(2)用到Prim算法求最小生成树,算法思想大体为: 设N=(V,E)是一个连通网,T=(U,TE)是N的最小生成树,TE是N中最小生成树中边的集合。 ①初始化:令U={u0|u0∈V},TE={}。其中u0是顶点集合V中的某个顶点。 ②选择:在所有u∈U,v∈V-U的边(u,v)∈E中,选择一条代价最小的边(ui,vj),将(ui,vj)并入集合TE,同时vj并入U。 ③反复执行步骤②,直至U=V为止。 TE必有n-1条边,则T为N的最小生成树。

【C源程序】

#include<stdio.h>
#include<stdlib.h>
#include<time.h> 
#define max 20
#define INFINITY 1000
typedef char ElemType;
typedef struct {
	ElemType vexs[max];
	int arcs[max][max];
	int vexnum,arcnum;
}MGraph; 
struct {
	ElemType adjvex;
	int lowcost;
}closedge[max];

//返回顶点下标 
int LocateVex(MGraph G,ElemType v)
{
	for(int i=0;i<G.vexnum;i++)
	{
		if(v==G.vexs[i])
			return i;
	}
	return -1;
}
//建立无向图邻接矩阵 
void CreatGraph(MGraph &G)
{
	int  i, j, k,m,n;
   	char v1, v2;
   	srand(time(0));
   printf("输入校园中景点数及弧数:\n");
   scanf( "%d%d", &G.vexnum, &G.arcnum );
   getchar(); 
   printf("输入校园中所有景点:\n" );
   for( i=0; i<G.vexnum; i++ )
   {   
   		G.vexs[i]=getchar(); 
		   getchar();   }
   for( i=0; i<G.vexnum; i++ )          //初始化邻接矩阵
      for( j=0; j<G.vexnum; j++ )
          G.arcs[i][j]=INFINITY;
   for( k=0; k<G.arcnum; k++ )
   {
   		int w;
   		printf("输入校园中的两个景点确定边:\n" );
       v1=getchar(); getchar();
       v2=getchar(); getchar();
       m= LocateVex(G,v1);  n= LocateVex(G,v2);
       printf("请输入边的权重:\n"); 
       scanf("%d",&w);
       getchar();
       G.arcs[m][n]=w;G.arcs[n][m]=w;
   }
   printf("邻接矩阵为:\n"); 
   for( i=0; i<G.vexnum; i++ ) 
   {      
      for( j=0; j<G.vexnum; j++ )
          printf("%d\t",G.arcs[i][j]);
    printf("\n"); 
}
}
//Prim(适用于边稠密的网) 
int MiniSpanTree_Prim(MGraph G,ElemType u)
{
	int k=LocateVex(G,u);
	for(int j=0;j<G.vexnum;j++)
	{
			if(j!=k)
			{
				closedge[j].adjvex=u;
				closedge[j].lowcost=G.arcs[k][j];
			}
	}
	closedge[k].lowcost=0;
	int minsum=0;
	for(int i=1;i<G.vexnum;i++)
	{
		int minCost=INFINITY;
		for(int j=0;j<G.vexnum;j++)//找最小值 
		{
			if(closedge[j].lowcost!=0&&closedge[j].lowcost<minCost){
				minCost = closedge[j].lowcost;
				k=j;
			}
		}
		printf("%c----%c %d\n",closedge[k].adjvex,G.vexs[k],closedge[k].lowcost);
		minsum+=closedge[k].lowcost;
		closedge[k].lowcost=0;
		for(int j=0;j<G.vexnum;j++)
		{
			if(closedge[j].lowcost!=0&&G.arcs[k][j]<closedge[j].lowcost)
			{
				closedge[j].adjvex = G.vexs[k];
				closedge[j].lowcost = G.arcs[k][j];
			}
		}
	}
	return minsum;
}
int main()
{
	 MGraph G;
    CreatGraph(G);                                                           //建立无向图的邻接矩阵 
    printf("请输入从哪个景点出发:\n");
    char u;
	scanf("%c",&u);
    printf("\n 最短路径权重之和为;%d.\n", MiniSpanTree_Prim(G,u));//输出路径与权值
	return 0;
 } 

【小结】

校园导航问题: 不足之处:将问题过于简单化,就简单实现建立赋权图的邻接矩阵存储结构,和用Prim算法求最短生成树,跟校园导航没有太多关系,不实用。 通过进行数据结构课程设计,对数据结构和算法有了进一步深刻的认识。也发现了自己很多问题。对许多重要的算法不能熟练的运用。仍需对代码进一步完善。

【参考文献】

[1] 赵永升,宋丽华,数据结构.北京:电子工业出版社,2019.
    
[2] 严蔚敏,数据结构(C语言版).北京:清华大学出版社,2007.