校园导航系统 数据结构

本文介绍了校园导航系统的数据结构设计,包括存储结构的设计思路,详细的实现方案,以及主程序的构建过程。


//本人第一次发博客,有什么不对的地方,还请谅解

主要功能设计

1.图的初始化由函数init()实现
2.学校景点介绍-简单循环输出
3.查看浏览路线迪杰斯特拉算法实现
4.查看两景点之间的最短路径弗洛伊德算法实现
5.景点信息查询对应输出
6.更改图信息图的基本操作
7.打印邻接矩阵输出邻接矩阵的值
8.退出退出系统

存储结构设计

class Vexsinfo {
        public int ID;
		public String name;
		public String  introduction;
		public boolean isVisited;
		public Vexsinfo(int id,String name, String a)
		{
			this.ID=id;
			this.name=name;
			this.introduction=a;
			this.isVisited=false;
		}
	}
	class MGraph/*图结构信息,邻接矩阵表示*/ {
	public Vexsinfo[]vexs;/*顶点信息*/
	public int [][]arcs;/*邻接矩阵,用整型值表示权值*/
	public int arcNum;/*边数*/
	public int vexNum;/*顶点数*/
	public MGraph(int maxVexsNum,int maxsize) {
		this.vexs=new Vexsinfo[maxVexsNum];
		this.arcs=new int[maxsize][maxsize];
		this.arcNum=maxVexsNum;
		this.vexNum=maxsize;
        init();
	}
	}

详细设计

/*显示景点所有信息景点*/
	public void introduceCompus()/*1.校园简介,显示各地点的编号`名称和简介*/
	   {
		System.out.format("\n\n%-6s%-30s%s\n","编号","景点名称","简介");
		System.out.print("                   \n");
		for(int i=0;i<this.vexNum;i++)
		System.out.format("%-6d%-30s%s\n",this.vexs[i].ID,this.vexs[i].name,this.vexs[i].introduction);
		System.out.print("                    \n");
					
        }
	/*查看浏览线路  */
	public void browsePath()/*显示从给定景点出发,到其他景点的最短路径 */
	    {
		/*迪杰斯特拉算法,求从顶点v0到其余顶点的最短路径p[][]及其带权长度d[v](最短路径的距离)  
		 * P[][]数组用于存放两顶点间是否有通路标志。若p[v][w]==1,则w是从v0到v的最短路径上的顶点*/
		int min,t=0,v0;  //v0为起始景点编号
		int []d=new int[35];
		int [][]p=new int[35][35];
		System.out.print("\n请输入一个起始景点编号");
		Scanner sc=new Scanner(System.in);
		v0=sc.nextInt();
		System.out.print("\n\n");
		while(v0<0||v0>this.vexNum)
		{
			System.out.print("\n你所输入的景点编号不存在");
			System.out.print("\n请重新输入");
			v0=sc.nextInt();
		}
		for(int v=0;v<this.vexNum;v++)
		{
			this.vexs[v].isVisited=false;  //初始化各顶点访问标志
			d[v]=this.arcs[v0][v];   //v0到各顶点v的权值赋值给d[v]
			/*初始化p[][]数组,各顶点间的路径全部设置为空路径0*/
			for(int w=0;w<this.vexNum;w++)
				p[v][w]=0;
			if(d[v]<1000)  //v0到v有边相连,修改p[v][v0]的值为1
			{
				p[v][v0]=1;
				p[v][v]=1; //各顶点自己到自己要连通
			}
		}
		d[v0]=0; //自己到自己的权值为0
		this.vexs[v0].isVisited=true; //v0的访问标志设为true,v属于s集
		/*对其余vexNum-1个顶点w,依次求v到w的最短路径*/
		for(int i=1;i<this.vexNum;i++)
		{ 
			min=1000;
			/*在未被访问的顶点中,查找与v0最近的顶点v*/
			for(int w=0;w<this.vexNum;w++)
				if(!this.vexs[w].isVisited&&d[w]<min)
				{
					t=w;
					min=d[w];
				}
				this.vexs[t].isVisited=true;//v的访问标志设置为1,v属于s集
				/*修改v0到其余各顶点w的最短路径权值d[w]*/
				for(int w=0;w<this.vexNum;w++)
					/*若w不属于s,且v到w有边相连*/
					if(!this.vexs[w].isVisited&&(min+this.arcs[t][w]<d[w]))
					{
						d[w]=min+this.arcs[t][w];//修改v0到w的权值d[w]
						/*所有v0到vde最短路径上的顶点x,都是v0到w的*/
						for(int x=0;x<this.vexNum;x++)
							p[w][x]=p[t][x];/*最短路径上的顶点*/
						p[w][w]=1;
					}
			}
				for(int v=0;v<this.vexNum;v++)/*输出v0到其他顶点v的最短路径*/
				{
					if(v!=v0)
						System.out.print(this.vexs[v0].name);//输出景点v0的景点名
					/*对图中每个顶点w,试探w是否是v0到v的最短路径上的顶点*/
					for(int w=0;w<this.vexNum;w++)
					{
						/*若w是,且w不等于v0,则输出该景点*/
						if(p[v][w]==1&&w!=v0&&w!=v)
							System.out.print("--->"+this.vexs[w].name);
					}
					System.out.print("--->"+this.vexs[v].name);
					System.out.print("\t总路线长为"+d[v]+"米\n\n");
				}
	}
		  public void showShortestPath()
				{
					/*用floyd算法,求各对顶点v和w间的最短路径p[][][]及其带权长度d[v][w]
					 * 若p[v][w][u]==1,则u是v到w的当前求得的最短路径上的顶点*/
					int j,k;
					int [][]d=new int [23][23];
					int [][][]p1=new int [23][23][23];
					/*初始化各对顶点v,w之间的起始距离d[v][w]及p[v][w][]数组*/
					for(int v=0;v<this.vexNum;v++)
						for(int w=0;w<this.vexNum;w++)
						{
							d[v][w]=this.arcs[v][w];//d[v][w]中存放v至w间初始权值
							/*初始化最短路径p[v][w][]数组,第3分量全部清0*/
							for(int u=0;u<this.vexNum;u++)
								p1[v][w][u]=0;
								if(d[v][w]<1000)/*如果v至w之间有边相连*/
								{
									p1[v][w][v]=1;//v是v至w最短路径上的顶点
									p1[v][w][w]=1;//w是v至w最短路径上的顶点
								}
						}
					/*求v至w的最短路径距离*/
					for(int u=0;u<this.vexNum;u++)
						/*对任意顶点u,试探其是否为v至w最短路径上的顶点*/
						for(int v=0;v<this.vexNum;v++)
							for(int w=0;w<this.vexNum;w++)
								/*从v经u到w的一条路径最短*/
								if(d[v][u]+d[u][w]<d[v][w])
								{
									/*若i是v至u的最短路径上的点,或i是u至w最短路径上的点,则i是v至w的最短路径上的点*/
									for(int i=0;i<this.vexNum;i++)
									p1[v][w][i]=(p1[v][u][i]==1||p1[u][w][i]==1)?1:0;
								}
        System.out.print("\n请输入`出发点和目的地编号:");
		Scanner sc=new Scanner(System.in);
		k=sc.nextInt();
		j=sc.nextInt();
		System.out.print("\n\n");
		


        while(k<0||k>this.vexNum||j<0||j>this.vexNum)
		{
			System.out.print("\n你所输入的景点编号不存在!");
			System.out.print("\n请重新输入出发点和目的地编号:\n\n");
			k=sc.nextInt();
			j=sc.nextInt();
			System.out.print("\n\n");
		}
		System.out.print(this.vexs[k].name);/*输出出发景点名称*/
		for(int u=0;u<this.vexNum;u++)
			if(p1[k][j][u]==1&&k!=u&&j!=u)/*输出最短路径上中间景点名称*/
				System.out.print(this.vexs[u].name);
		System.out.print(this.vexs[j].name);/*输出目的地景点名称*/
		System.out.print("\n\n\n总长为"+d[k][j]+"米\n\n\n");
	}
			
//景点信息查询
	public void showVexsinfo(){
		System.out.print("\n请输入要查询的景点编号:");
		Scanner sc=new Scanner(System.in);
		int k=sc.nextInt();
		while(k<0||k>this.vexNum){
			System.out.print("\n你所输入的景点编号不存在!");
			System.out.print("\n请重新输入:");
			k=sc.nextInt();
		}
		System.out.println("\n\n编号:"+this.vexs[k].ID);
		System.out.println("\n\n景点名称:"+this.vexs[k].name);
		System.out.println("\n\n介绍:"+this.vexs[k].introduction);
	}

//查找景点在图中的序号
		public int locateVex(int v){
			for(int i=0;i<this.vexNum;i++){
				if(v==this.vexs[i].ID)
			       return i;//找到,返回顶点序号i
			}
			return -1;       //否则,返回-1
		}

//更改图信息
		public int changeGraph(){
			int yourChoice;
			Scanner sc=new Scanner(System.in);
			do{
				yourChoice=0;
				System.out.print("\n-----------------------欢迎使用导游程序----------------------\n");
				System.out.print("\n        请选择要完成的操作!            \n\n");
				System.out.print("\n            菜单选择                        \n\n");
				System.out.print("      1.再次建图                   2.删除结点       \n");
				System.out.print("      3.删除边                       4.增加结点         \n");
				System.out.print("      5.增加边                       6.更新信息         \n");
				System.out.print("      7.打印邻接矩阵           8.返回上一级     \n");
				System.out.print("\n---------------------------------------------------------\n");
				System.out.print("\n请输入你的选择:");
				yourChoice=sc.nextInt();
				switch(yourChoice){
				case 1:recreate(); break;//重建图,调用(11)
				case 2:delVex();break;//删除顶点
				case 3:delArc();break;//删除边
				case 4:addVex();break;//增加顶点
				case 5:addArc();break;//增加边
				case 6:modify();break;//更新图的信息,调用(16) 
				case 7:printMatrix();break;//输出邻接矩阵,调用(7) 
				case 8:return 1;//返回主菜单
				default: System.out.print("输入选择不明确,请重新选择\n");break;
				}
			}while(yourChoice!=8);
			return 1;
		}
		//重建构建图,以邻接矩阵表示
		public int recreate(){//重建图,以图的邻接矩阵存储图
			int j,m,n,v0,v1,distance;
			System.out.print("请输入图的顶点数和边数:\n");
			Scanner sc=new Scanner(System.in);
			this.vexNum=sc.nextInt();
			this.arcNum=sc.nextInt();
			System.out.print("下面请输入景点的信息:\n");
			for(int i=0;i<this.vexNum;i++){//构造顶点向量
				System.out.print("请输入景点的编号:");
				this.vexs[i].ID=sc.nextInt();
				System.out.print("\n请输入景点的名称:");
				this.vexs[i].name=sc.nextLine();
				System.out.print("\n请输入景点的简介:");
				this.vexs[i].introduction=sc.nextLine();
			}
			for(int i=0;i<this.arcNum;i++)//初始化邻接矩阵
				for(j=0;j<this.arcNum;j++)
					this.arcs[i][j]=1000;
			System.out.print("下面请输入图的边的信息:\n");
			for(int i=1;i<=this.arcNum;i++){

System.out.print("第"+i+"条边的起点 终点 长度为:");
			v0=sc.nextInt();
			v1=sc.nextInt();
			distance=sc.nextInt();
			m=locateVex(v0);
			n=locateVex(v1);
			if(m>=0&&n>=0){
				this.arcs[m][n]=distance;
				this.arcs[n][m]=this.arcs[m][n];
			}
		}
			return 1;
		}
		public int delVex()/*删除地点(顶点)*/
		{
			if(this.vexNum<=0)
			{
				System.out.print("图中已无顶点");
				return 1;
			}
			System.out.print("\n下面请输入你要删除的景点编号:");
			Scanner sc=new Scanner(System.in);
			int v=sc.nextInt();
			while(v<0||v>this.vexNum)
			{
				System.out.print("\n输入错误!请重新输入");
				v=sc.nextInt();
			}
			int m=locateVex(v);
			if(m<0)
			{
				System.out.print("顶点“+v+”不存在!");
				return 1;
			}
			/*对顶点信息所在顺序表进行删除m点的操作*/
		    for(int i=m;i<this.vexNum;i++)
		    {
		    	this.vexs[i].ID=this.vexs[i+1].ID;
		    	this.vexs[i].name=this.vexs[i+1].name;
		    	this.vexs[i].introduction=this.vexs[i+1].introduction;
		    }
		    /*对原邻接矩阵,删除该顶点到其余顶点的邻接关系。分别删除相应的行和列*/
		    for(int i=m;i<this.vexNum-1;i++)   /*行*/
		    	for(int j=0;j<this.vexNum;j++)    /*列*/
		    		/*二维数组,从第m+1行开始依次往前移一行,即删除m行*/
		    		this.arcs[i][j]=this.arcs[i+1][j];
		    
 for(int i=m;i<this.vexNum-1;i++)   /*行*/
		    	for(int j=0;j<this.vexNum;j++)    /*列*/
		    		/*二维数组,从第m+1行开始依次往前移一行,即删除m列*/
		   this.arcs[j][i]=this.arcs[j][i+1];
		    this.vexNum--;
	System.out.print("顶点"+m+"删除成功!");
		    return 1;
		    
}
        public int delArc()   /*删除边*/
		{
			if(this.arcNum<=0)
			{
				System.out.print("图中已边,无法删除。");
				return 1;
			}
			System.out.print("\n下面请输入你要删除的边的起点和终点点编号:");
			Scanner sc=new Scanner(System.in);
			int v0=sc.nextInt();
			int v1=sc.nextInt();
			int m=locateVex(v0);
			if(m<0)
			{
				System.out.print("顶点“+v0+”不存在!");
				return 1;
			}
			int n=locateVex(v1);
			if(n<0)
			{
				System.out.print("顶点“+v1+”不存在!");
				return 1;
			}
			this.arcs[m][n]=1000;
			this.arcs[n][m]=1000;
			this.arcNum--;
			System.out.print("边(“+v0+“,”+v1+”)删除成功!");
			return 1;
		}
		public int addVex()   /*添加景点(顶点)*/
		{
			System.out.print("请输入你要增加的结点信息:");
			System.out.print("\n编号:");
			Scanner sc=new Scanner(System.in);
			this.vexs[this.vexNum].ID=sc.nextInt();
			System.out.print("\n名称:");
			this.vexs[this.vexNum].name=sc.nextLine();
			System.out.print("\n简介:");
			this.vexs[this.vexNum].introduction=sc.nextLine();
			this.vexNum++;
			/*对原邻接矩阵新增加的一行及一列进行初始化*/
		    for(int i=0;i<this.vexNum;i++) 
		    {
		    	this.arcs[this.vexNum-1][i]=1000;/*最后一行(新增的一行)*/
		    	this.arcs[i][this.vexNum-1]=1000;/*最后一列(新增的一列)*/
		    }
		    return 1;
		}
		public int addArc()   /*添加边*/
		{
			int m,n,distance;
			System.out.print("\n请输入边的起点和终点编号,权值:");
			Scanner sc=new Scanner(System.in);
			m = sc.nextInt();
			n = sc.nextInt();
			distance = sc.nextInt();
			while(m<0||m>this.vexNum||n<0||n>this.vexNum)
			{
				System.out.print("输入错误,请重新输入");
				m = sc.nextInt();
				n = sc.nextInt();
			}
			if(locateVex(m)<0)
			{
				System.out.print("此顶点“+m+”不存在");
				return 1;
			}
			if(locateVex(n)<0)
			{
				System.out.print("此顶点“+n+”不存在");
				return 1;
			}
			this.arcs[m][n]=distance;
			this.arcs[n][m]=this.arcs[m][n];/*对称赋值*/
			System.out.print("边(“+m+“,”+n+”)添加成功!");
			return 1;
		}

        public int modify()/*更新图的部分信息,返回值:1*/{
			System.out.print("\n下面请输入你要修改的景点的个数:\n");
		    Scanner sc=new Scanner(System.in);
		    int changenum=sc.nextInt();
		    while(changenum<0||changenum>this.vexNum){
		    	System.out.print("\n输入错误!请重新输入");
		    	changenum=sc.nextInt();
		    }
		    for(int i=0;i<changenum;i++){
		    	System.out.print("\n请输入景点的编号:");
		    	int m=sc.nextInt();
		    	int t=locateVex(m);
		    	System.out.print("\n请输入景点的名称:");
		    	this.vexs[t].name=sc.nextLine();
		    	System.out.print("\n请输入景点的简介:");
		    	this.vexs[t].introduction=sc.nextLine();
		    }
		    System.out.print("\n下面请输入你要更新的边数");
		    changenum=sc.nextInt();
		    while(changenum<0||changenum>this.arcNum){
		    	System.out.print("\n输入错误!请重新输入");
		    	changenum=sc.nextInt();
		    }
		    System.out.print("\n下面请输入更新边的信息:\n");
		    for(int i=1;i<=changenum;i++){
		    	System.out.print("\n修改的第"+i+"条边的起点、终点的长度为:");
		    	int v0=sc.nextInt();
		    	int v1=sc.nextInt();
		    	int distance=sc.nextInt();
		    	int m=locateVex(v0);
		    	int n=locateVex(v1);
		    	if(m>=0&&n>=0){
		    		this.arcs[m][n]=distance;
		    		this.arcs[n][m]=this.arcs[m][n];
		    	}
		    }
		    System.out.print("图信息更新成功!");
		    return 1;
		    }
			public void printMatrix() /*打印学校地图的邻接矩阵*/{
				for(int i=0;i<this.vexNum;i++){
					System.out.print("\n");
					for(int j=0;j<this.vexNum;j++){
						if(this.arcs[i][j]==1000)
							System.out.print(" * ");
						else
							System.out.print(this.arcs[i][j]);
					}
				}
				System.out.print("\n");
			}
	  public void init ()/*通过初始化,一次性得到具有若干点的地图*/{
				
String []names={"学院侧门","音乐广场","西办公楼","东办公楼",
				"西A、西B教学楼","东A、东B教学楼","实验楼",
				"正阳餐厅","学生宿舍1-4栋",
				"学生宿舍5-6栋",
						"体育场","中心广场","学生宿舍10-12栋",
						"学生宿舍7-9栋","小广场","晨曦餐厅","新力路",
						"第二教学楼","图书馆、第二实验大楼","体育馆",
						"霞光餐厅","学生宿舍13、14、17、18栋","学生宿舍15-16栋",};
				String []introduces={"学院主路要进出口,离公交车站很近,9370351154305等多路公交车",
				"音乐广场,学院大门","学院西办公楼,楼高6层",
						"学院东办公楼,楼高6层","西A、西B教学楼,楼高5层",
						"东A、东B教学楼,楼高5层","实验大楼,楼高6层",
						"正阳餐厅,学生食堂","学生宿舍1-4栋,楼高6层",
						"学生宿舍4-6栋,楼高6层","体育场",
						"中心广场,在实验楼、体育场、晨曦餐厅附近",
						"学生宿舍10-12栋,楼高6层",
						"学生宿舍7-9栋,楼高6层","小广场,晨曦餐厅附近",
						"晨曦餐厅、学生食堂","红区和蓝区之间的大门及通道",
						"第二教学楼,楼高六层","图书馆、第二实验大楼",
						"体育馆","霞光餐厅,学生食堂",
						"学生宿舍13、14、17、18栋,楼高六层",
						"学生宿舍15-16栋,楼高六层"};
				for(int i=0;i<this.vexNum;i++)/*依次设置图的各顶点信息*/{
					this.vexs[i]=new Vexsinfo(i,names[i],introduces[i]);
				}
				for(int i=0;i<this.vexNum;i++)/*先初始化图的邻接矩阵*/
					for(int j=0;j<this.vexNum;j++)
						this.arcs[i][j]=1000;/*1000表示无边*/
				this.arcs[0][1]=185;this.arcs[0][11]=171;this.arcs[1][2]=69;
				this.arcs[1][3]=69;this.arcs[1][6]=180;this.arcs[1][16]=196;
				this.arcs[2][3]=86;this.arcs[2][4]=85;this.arcs[3][5]=85;
				this.arcs[4][5]=120;this.arcs[4][6]=65;this.arcs[4][16]=170;
				this.arcs[5][6]=65;this.arcs[6][7]=302;this.arcs[6][8]=220;
				this.arcs[6][9]=246;this.arcs[7][8]=97;this.arcs[7][9]=97;
				this.arcs[9][10]=219;this.arcs[10][11]=176;this.arcs[10][12]=244;
				this.arcs[11][12]=100;this.arcs[11][13]=79;this.arcs[11][14]=126;
				this.arcs[12][14]=69;this.arcs[13][14]=106;this.arcs[14][15]=142;
				this.arcs[16][17]=73;this.arcs[16][20]=246;this.arcs[16][22]=72;
				this.arcs[17][18]=163;this.arcs[18][19]=143;this.arcs[19][20]=90;
				this.arcs[20][21]=161;this.arcs[21][22]=150;
				for(int i=0;i<this.vexNum;i++)/*邻接矩阵是对称矩阵,对称赋值*/
					for(int j=0;j<this.vexNum;j++)
						this.arcs[j][i]=this.arcs[i][j];
			}

主程序设计

import java.util.*;
public  class Teat  {
public static void main(String[] args) {
			// TODO Auto-generated method stub
	        int yourChoice;
	        String iSExit="n";
	        MGraph campus=new MGraph(23,23);
	        Scanner in=new Scanner (System.in);
	        do {
	        	yourChoice=0;
	        	System.out.print("\n--------------------------------欢迎使用校园导游系统----------------------------------\n");
	        	System.out.print("\n                            欢迎来到电子科技大学成都学院!\n\n");
	        	System.out.print("\n                     菜 单 选 择\n\n ");
	        	System.out.print("\n             1.学校景点介绍                         2.查看游览路线\n\n");
	        	System.out.print("\n             3.查询景点间最短路径            4.景点信息查询\n\n");
	        	System.out.print("\n             5.更改图信息                              6.打印领接矩阵\n\n");
	        	System.out.print("\n             7.退出\n");
	        	System.out.print("\n---------------------------------------------------------------------------------\n");
	        	System.out.print("\n请输入你的选择\n");
	        	yourChoice=in.nextInt();
	        	switch(yourChoice)
	        	{
	        	case 1:campus.introduceCompus(); break;
	        	case 2:campus.browsePath(); break;
	        	case 3:campus.showShortestPath(); break;
	        	case 4:campus.showVexsinfo(); break;
	        	case 5:campus.changeGraph(); break;
	        	case 6:campus.printMatrix(); break;
	        	case 7:
	        		System.out.print("您确定要退出系统么?(Y/N):");
	        		iSExit=in.nextLine();
	        		if(iSExit=="Y"||iSExit=="y")
	        			System.exit(0);
	        		else
	        			iSExit="n";
	        		break;
	        		default:
	        			System.out.print("输入选择不明确,请重新输入\n");
	        			break;
	        	}
	        }
	        while(yourChoice!=7||iSExit=="n");
	        in.close();
		}
}

评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值