学校的校园景点平面图(校园景点迷你地图C++&数据结构)

设计要求:

(1)建图
以图中顶点表示主要景点,并存放景点的编号、名称、简介等信息;
(2)查询
该系统可以查询景点的信息;
查询图中任意两个景点间的最短路径;
查询图中所有景点间的最短路径;
查询图中任意两个景点间的所有路径。
(3)更新
更新景点间路径长度;
在两个景点之间添加一条路径;
删除两个景点之间的一条路径;
增添一个景点;
去除一个景点;
更改景点的简介。

功能实现

(1)建图
首先画出所要建立的地图的形象版

为了方便使用图论的知识来完成上述所要实现的功能,将这个形象图抽象化,变成图:

邻接矩阵1:(由createMTGraph()函数建立的邻接矩阵)

邻接矩阵2:(由createMTGraph1()函数建立的邻接矩阵)

接下来使用数据结构的知识用编程语言表示这个图:

#define numedges 100     //最大边数
#define numvertices 13 //最大顶点个数 typedef string vertexdata; //顶点数据类型
typedef int  edgedata;   //边上权值类型
typedef int *listofnode;
typedef struct node{vertexdata verlist[numvertices]; //顶点表,verlist[i]类型为string,存放顶点名称vertexdata info[numvertices];//存放顶点简介edgedata edge[numvertices][numvertices]; //邻接矩阵--边表,可视为边之间的关系,存放权值int n,e;//图中当前的顶点个数与边数
}MTGraph;

这是使用邻接矩阵表示有向图。
注:为什么刚才抽象出来的图是无向图,而我要使用有向图呢?
因为分析这个地图要实现的功能,有“查询图中任意两个景点间的最短路径; 查询图中所有景点间的最短路径;查询图中任意两个景点间的所有路径。”,这些功能一定会用到那个著名的算法:Floyd算法,而这个算法是要求使用有向图的;而且使用邻接矩阵表示的图,无论是有向图还是无向图,都是可以互相转化的,简单地说就是:双向有向图==无向图,即把有向图每对顶点之间的有向边都变为两条方向相反的有向边!这也不会费多少功夫和资源。

(2)对该图的一些基本操作:

//判断两个顶点之间是否有边
bool isEdge(MTGraph &G,int v1,int v2){return G.edge[v1][v2]!=INF;
}//创建一个新的顶点
void newnode(MTGraph &G,vertexdata v){G.verlist[G.n]=v;//G.n=11G.n++;//G.n=12for(int i=0;i<G.n+1;i++){//i<12  (i:0~11)G.edge[G.n-1][i]=INF;G.edge[i][G.n-1]=INF;}
} //更改两个景点v1,v2之间的路径长度为juli
void chg(MTGraph &G,int v1,int v2,int juli){if(isEdge(G,v1,v2)){int temp=G.edge[v1][v2];G.edge[v1][v2]=juli;G.edge[v2][v1]=juli;cout<<G.verlist[v1]<<"和"<<G.verlist[v2]<<"这两个景点之间的路径长度从"<<temp<<"更改为"<<juli<<endl;}else{cout<<"这两个景点之间没有直接路径,更新失败!"<<endl;//return;}}//删除一个顶点
void delnode(MTGraph &G,int v){int i,j;for(i=0;i<G.n;i++)if(G.edge[v][i]!=INF){G.edge[v][i]=INF;G.edge[i][v]=INF;  G.e==G.e-2;}// 删除一个顶点 之后表示该图的邻接矩阵 也会改变 for(i=v+1;i<G.n;i++)//行 for(j=0;j<G.n;j++)//列 G.edge[i-1][j]=G.edge[i][j];   for(i=v+1;i<G.n;i++)//列 for(j=0;j<G.n-1;j++)//行 G.edge[j][i-1]=G.edge[j][i];for(i=v+1;i<G.n;i++)G.verlist[i-1]=G.verlist[i];G.n--;
}//添加1条V1->V2的有向边(建立图时用)
void setsucc1(MTGraph &G,int v1,int v2,int w){if(isEdge(G,v1,v2))return;G.e++;G.edge[v1][v2]=w;//G.edge[v2][v1]=w;
}//在V1和V2这两个景点之间添加一条路径(添加路径时用)
void setsucc2(MTGraph &G,int v1,int v2,int w){if(isEdge(G,v1,v2)){cout<<G.verlist[v1]<<"和"<<G.verlist[v2]<<"这两个景点之间已经存在路径,不需要在添加路径!"<<endl;return;}G.e++;G.edge[v1][v2]=w;G.edge[v2][v1]=w;cout<<"成功在"<<G.verlist[v1]<<"和"<<G.verlist[v2]<<"这两个景点之间添加一条长度为"<<w<<"的路径"<<endl;
}//删除V1->V2的和V2->V1的边;删除V1和V2这两个景点之间的一条路径
void delsucc(MTGraph &G,int v1,int v2){if(!isEdge(G,v1,v2)){cout<<G.verlist[v1]<<"和"<<G.verlist[v2]<<"这两个景点之间不存在路径,不需要在删除路径!"<<endl;return;}int temp=G.edge[v1][v2];G.e--;G.edge[v1][v2]=INF;G.edge[v2][v1]=INF; //G.edge[v1][v2]=0;//G.edge[v2][v1]=0; cout<<"成功删除"<<G.verlist[v1]<<"和"<<G.verlist[v2]<<"这两个景点之间一条长度为"<<temp<<"的路径"<<endl;
} //v的直接后继
int *succ(MTGraph G,int v){int *ret=new int[numvertices];int i,k;for(i=0;i<G.n;i++){if(G.edge[v][i])ret[k++]=i;}ret[k]=-1;return ret;
}//v的直接前驱
int *pre(MTGraph G,int v){int *ret=new int[numvertices];int i,k;for(i=0;i<G.n;i++){if(G.edge[i][v])ret[k++]=i;}ret[k]=-1;return ret;
}

建图函数:
1.

//构建图之1,包括表示该图的邻接矩阵(元素由INF和每对顶点间的路径长度组成),图中顶点的名称和简介
void createMTGraph(MTGraph &G){//  int i,j,x,y,e,w;int i,j,n=11,e=30,x,y,w;//int i,j,n=3,e=6,x,y,w;//memset(G.edge,0,sizeof(G.edge));for(i=0;i<numvertices;i++)for(j=0;j<numvertices;j++)G.edge[i][j]=INF;/*cout << "请输入图中当前的顶点个数:";cin>>n;//n=11G.n=n;cout <<endl;cout << "请输入图中当前的边数:";cin>>e;//e=30//G.e=e;*/G.n=n;/*for(i=0;i<n;i++){cout << "请输入顶点"<<i<<"的名称:";cin>>G.verlist[i];//顶点表,verlist[i]类型为string,存放顶点名称cout << "请输入顶点"<<i<<"的简介:";cin>>G.info[i];//存放顶点简介}*/vertexdata str1[13]={"大门","厚学楼","浦江","操场","大礼堂","宿舍","西苑","沉毅广场","镜湖","东苑","图书馆"};for(int i=0;i<13;i++){G.verlist[i]= str1[i];}     //存放景点简介的字符串数组 vertexdata str2[13]={"大门是南京工业大学的门面招牌,气势恢宏!","厚学楼是学习圣地,在这里总是能看到莘莘学子发奋苦读的情景!","浦江是美食天堂,这里有各式各样的特色美食!","操场十分辽阔整洁,是学生放松锻炼的好地方!","大礼堂是学校举办各种文艺演出的地方,周末还会放电影哟!","宿舍是学生们休息,娱乐,学习的地方!","西苑景色很美,有绿水,有大树,还有一个很时尚的网红餐厅!","沉毅广场也是学校的一大门面担当,那个古老的大铜鼎更是令人赞叹!","镜湖很美,水面辽阔,平静如镜,还有荷花!","东苑有一个拥有穹顶的食堂,很有艺术感,还上过电视哦!","图书馆是个知识宝库,里面的学生也是络绎不绝!"};for(int i=0;i<13;i++){G.info[i]= str2[i];}//景点平面图的邻接矩阵edgedata edge1[13][13]={ {INF,50,INF,INF,60,INF,INF,INF,INF,INF,INF,INF,INF},{50,INF,80,INF,80,INF,INF,40,INF,INF,INF,INF,INF},{INF,80,INF,20,INF,INF,INF,INF,INF,INF,INF,INF,INF},{INF,INF,20,INF,INF,INF,INF,160,INF,INF,INF,INF,INF},{60,80,INF,INF,INF,60,INF,INF,INF,INF,INF,INF,INF},{INF,INF,INF,INF,60,INF,120,280,INF,INF,INF,INF,INF},{INF,INF,INF,INF,INF,120,INF,INF,INF,100,INF,INF,INF},{INF,40,INF,160,INF,280,INF,INF,500,INF,400,INF,INF},{INF,INF,INF,INF,INF,INF,INF,500,INF,300,200,INF,INF},{INF,INF,INF,INF,INF,INF,100,INF,300,INF,INF,INF,INF},{INF,INF,INF,INF,INF,INF,INF,400,200,INF,INF,INF,INF}};for(int i=0;i<13;i++){//我用上面的二维数组代替此地图初始化的过程 ,不会破坏其可拓展性 ,而且不用每次运行程序都手动输入一遍邻接矩阵 for(int j=0;j<13;j++){//想换一个地图就只要更改这个邻接矩阵即可 G.edge[i][j]=edge1[i][j];}}/*for(i=0;i<e;i++){//void setsucc(MTGraph &G,int v1,int v2,int w)在改变G的e(G.e),,怪不得一直输入起点终点无法退出cout << "请输入起点:";cin>>x;cout << "请输入终点:";cin>>y;cout << "请输入权值:";cin>>w;setsucc1(G,x,y,w);//e为奇数时要这样建立图,每条边都要输入一遍,要输入e对顶点}*//*for(i=0;i<e/2;i++){//void setsucc(MTGraph &G,int v1,int v2,int w)在改变G的e(G.e),,怪不得一直输入起点终点无法退出cout << "请输入起点:";cin>>x;cout << "请输入终点:";cin>>y;cout << "请输入权值:";cin>>w;setsucc(G,x,y,w);setsucc(G,y,x,w);//e为偶数时可以这样建立图,输入一半的边即可,只要输入e/2对顶点}*/
}
//构建图之2(改变了邻接矩阵的表示:有边G.edge[i][j]==1,没有边G.edge[i][j]==INF),这个建图函数是为了服务功能10:查询图中任意两个景点间的所有路径
void createMTGraph1(MTGraph &G){//  int i,j,x,y,e,w;int i,j,n=11,e=30,x,y,w;//int i,j,n=3,e=6,x,y,w;//memset(G.edge,0,sizeof(G.edge));for(i=0;i<numvertices;i++)for(j=0;j<numvertices;j++)G.edge[i][j]=INF;G.n=n;vertexdata str1[13]={"大门","厚学楼","浦江","操场","大礼堂","宿舍","西苑","沉毅广场","镜湖","东苑","图书馆"};for(int i=0;i<13;i++){G.verlist[i]= str1[i];}        //存放景点简介的字符串数组 vertexdata str2[13]={"大门是南京工业大学的门面招牌,气势恢宏!","厚学楼是学习圣地,在这里总是能看到莘莘学子发奋苦读的情景!","浦江是美食天堂,这里有各式各样的特色美食!","操场十分辽阔整洁,是学生放松锻炼的好地方!","大礼堂是学校举办各种文艺演出的地方,周末还会放电影哟!","宿舍是学生们休息,娱乐,学习的地方!","西苑景色很美,有绿水,有大树,还有一个很时尚的网红餐厅!","沉毅广场也是学校的一大门面担当,那个古老的大铜鼎更是令人赞叹!","镜湖很美,水面辽阔,平静如镜,还有荷花!","东苑有一个拥有穹顶的食堂,很有艺术感,还上过电视哦!","图书馆是个知识宝库,里面的学生也是络绎不绝!"};for(int i=0;i<13;i++){G.info[i]= str2[i];}//景点平面图的邻接矩阵edgedata edge1[13][13]={ {INF,1,INF,INF,1,INF,INF,INF,INF,INF,INF,INF,INF},{1,INF,1,INF,1,INF,INF,1,INF,INF,INF,INF,INF},{INF,1,INF,1,INF,INF,INF,INF,INF,INF,INF,INF,INF},{INF,INF,1,INF,INF,INF,INF,1,INF,INF,INF,INF,INF},{1,1,INF,INF,INF,1,INF,INF,INF,INF,INF,INF,INF},{INF,INF,INF,INF,1,INF,1,1,INF,INF,INF,INF,INF},{INF,INF,INF,INF,INF,1,INF,INF,INF,1,INF,INF,INF},{INF,1,INF,1,INF,1,INF,INF,1,INF,1,INF,INF},{INF,INF,INF,INF,INF,INF,INF,1,INF,1,1,INF,INF},{INF,INF,INF,INF,INF,INF,1,INF,1,INF,INF,INF,INF},{INF,INF,INF,INF,INF,INF,INF,1,1,INF,INF,INF,INF}};for(int i=0;i<13;i++){//我用上面的二维数组代替此地图初始化的过程 ,不会破坏其可拓展性 ,而且不用每次运行程序都手动输入一遍邻接矩阵 for(int j=0;j<13;j++){//想换一个地图就只要更改这个邻接矩阵即可 G.edge[i][j]=edge1[i][j];}}}

(3)各种功能的实现
1.查询景点的信息;

//查询景点v的信息(简介)
void printinfo(MTGraph g,int v){//ifcout<<"景点"<<g.verlist[v]<<"的简介:"<<g.info[v]<<endl;
}

在main()函数中对应着case 1:

case 1:int x1;cout<<"请输入想要查询信息的景点的代号:";cin>>x1;cout<<endl;printinfo(g,x1);break;

2.查询图中任意两个景点间的最短路径;
该功能由Floyd算法和配合Floyd算法使用的输出函数组成:

//求图中任意两个景点间的最短路径---Floyd算法
void floyd(MTGraph g,int d[numvertices][numvertices],int p[numvertices][numvertices]){int i,j,k;for(i=0;i<g.n;i++){for(j=0;j<g.n;j++){d[i][j]=g.edge[i][j];p[i][j]=-1;}}for(k=0;k<g.n;k++)for(i=0;i<g.n;i++)for(j=0;j<g.n;j++){if(d[i][j]>d[i][k]+d[k][j]){d[i][j]=d[i][k]+d[k][j];p[i][j]=k;}}
}//O(g.n^3) //输出U->V的最短路径
void printpath(MTGraph g,int p[numvertices][numvertices],int u, int v){int k;if(p[u][v]==-1){cout<<"<"<<g.verlist[u]<<"--->"<<g.verlist[v]<<">";return;}k=p[u][v];printpath(g,p,u,k);printpath(g,p,k,v);
}

在main()函数中对应着case 2:

case 2:floyd(g,d,p);cout<<"请输入想要查询最短路径的两个景点的编号:"<<endl;cin>>v1>>v2; cout<<g.verlist[v1]<<"和"<<g.verlist[v2]<<"之间的最短路径为:"<<endl;cout<<setiosflags(ios::left)<<g.verlist[v1]<<"->"<<g.verlist[v2]<<":"; printpath(g,p,v1,v2);cout<<"      ";cout<<"该路径的长度为:"<<d[v1][v2]<<"米"<<endl;               break;

3.查询图中所有景点间的最短路径;
该功能也是由Floyd算法和配合Floyd算法使用的输出函数组成,只是不止输出要查询的2个顶点之间的最短路径,而是输出每对顶点的:
在main()函数中对应着case 3:

case 3:floyd(g,d,p);cout<<"每对顶点之间最短路径为:"<<endl;for(i=0;i<g.n;i++){for(j=0;j<g.n;j++){if(d[i][j]==INF)continue;else{if(i!=j){//&&g.egdge[i][j]!=INF//cout<<setiosflags(ios::left)<<i<<g.verlist[i]<<"->"<<j<<g.verlist[j]<<":"; cout<<setiosflags(ios::left)<<g.verlist[i]<<"->"<<g.verlist[j]<<":"; printpath(g,p,i,j);cout<<endl;}}      }  } break;

4.查询图中任意两个景点间的所有路径;
这个功能应该是对我来说最烧脑的一个,它是我最后实现的一个功能,所以我把它放在了case 10;
首先在mian()函数开头定义好case 10中要使用的变量并把图建好:

int main(){int i,j;int start_num;//起点编号 int node_num;//终点编号 int d[numvertices][numvertices],p[numvertices][numvertices];//,a[numvertices][numvertices]MTGraph g;MTGraph g1;createMTGraph(g);//建立图 gcreateMTGraph1(g1);//建立图 g1

接着去case 10中编写"求图中任意两个景点间的所有路径"的算法:

case 10:{ bool is_in_stack[numvertices];is_in_stack[numvertices]={0};stack<int>node_stack;int c_position;c_position = 0;vector<vector<int> >paths;//存储所有路径vector<int>path;//存储单条路径cout<<"请输入想要查询所有路径的两个景点的编号:"<<endl;cin>>start_num>>node_num; //start_num和node_num可取0~10 ,但最好不要一样 cout<<g.verlist[start_num]<<"和"<<g.verlist[node_num]<<"之间的所有路径为:"<<endl;//思考过程 //先测试从0--->10的所有路径 //已然解决了,横空出世! //接下来看看任意两点之间的所有路径 //完美! //还有瑕疵,就是 起点编号要小于终点 //又一个瑕疵,连续使用10号功能就会输出不变 ,现在也解决了 //起点入栈node_stack.push(start_num);is_in_stack[0] = 1;//设置起点已入栈,1表示在栈中,0 表示不在int top_element;//记录栈顶元素int tmp;while (!node_stack.empty()){top_element = node_stack.top();//查看栈顶元素,判断是否已经到达终点if (top_element == node_num)//若到达终点,输出路径,弹出栈中两个点,设置出栈状态{while (!node_stack.empty()){tmp = node_stack.top();node_stack.pop();path.push_back(tmp);}paths.push_back(path);//将路径加入路径组for (vector<int>::reverse_iterator rit = path.rbegin(); rit != path.rend(); rit++){node_stack.push(*rit);}path.clear();//清除单条路径node_stack.pop();is_in_stack[top_element] = 0;c_position = node_stack.top();//记录位置,以便从该位置之后进行搜索top_element = node_stack.top();node_stack.pop();is_in_stack[top_element] = 0; //cout << vis[top_element];}else{int i = 0;for (i = c_position + 1; i <node_num + 2; i++){if (is_in_stack[i] == 0 && g1.edge[top_element][i] != INF)//未入栈,而且节点之间有边相连{is_in_stack[i] = 1;//stack Innode_stack.push(i);//入栈c_position = 0;//位置置零,是因为从记录的位置开始搜索完以后,在新的行上搜索,自然从零开始,以免漏掉节点break;}}if (i == node_num + 2){top_element = node_stack.top();is_in_stack[top_element] = 0;c_position = node_stack.top();node_stack.pop();}}}//========================  输出 ==========================//逆向for (int i = 0; i <paths.size(); i++){cout << "路径" << i << ": ";for (int j = paths[i].size()-1; j >=0; j--){if (j == 0){//cout << paths[i][j];cout << g1.verlist[ paths[i][j] ];}else{//cout << paths[i][j] << "->";cout << g1.verlist[ paths[i][j] ] << "->";}}cout << endl;}//========================  输出 ==========================     break;}

5.更新景点间路径长度;

//更改两个景点v1,v2之间的路径长度为juli
void chg(MTGraph &G,int v1,int v2,int juli){if(isEdge(G,v1,v2)){int temp=G.edge[v1][v2];G.edge[v1][v2]=juli;G.edge[v2][v1]=juli;cout<<G.verlist[v1]<<"和"<<G.verlist[v2]<<"这两个景点之间的路径长度从"<<temp<<"更改为"<<juli<<endl;}else{cout<<"这两个景点之间没有直接路径,更新失败!"<<endl;//return;}}

在main()函数中对应着case 4:

case 4://int v1,v2,w;cout<<"请输入想要更新路径长度的两个景点的编号:"<<endl;cin>>v1>>v2;if(!isEdge(g,v1,v2)){cout<<"这两个景点之间没有直接路径,更新失败!"<<endl;break;}cout<<"请输入想要设置的新路径长度:";cin>>w;chg(g,v1,v2,w);break;

6.在两个景点之间添加一条路径;

//在V1和V2这两个景点之间添加一条路径(添加路径时用)
void setsucc2(MTGraph &G,int v1,int v2,int w){if(isEdge(G,v1,v2)){cout<<G.verlist[v1]<<"和"<<G.verlist[v2]<<"这两个景点之间已经存在路径,不需要在添加路径!"<<endl;return;}G.e++;G.edge[v1][v2]=w;G.edge[v2][v1]=w;cout<<"成功在"<<G.verlist[v1]<<"和"<<G.verlist[v2]<<"这两个景点之间添加一条长度为"<<w<<"的路径"<<endl;
}

在main()函数中对应着case 5:

case 5://int v1,v2,w;cout<<"请输入想要添加路径的两个景点的编号:"<<endl;cin>>v1>>v2;if(isEdge(g,v1,v2)){cout<<g.verlist[v1]<<"和"<<g.verlist[v2]<<"这两个景点之间已经存在路径,不需要在添加路径!"<<endl;break;}cout<<"请输入想想要添加的路径的长度:";cin>>w;setsucc2(g,v1,v2,w);break;

7.删除两个景点之间的一条路径;

//删除V1->V2的和V2->V1的边;删除V1和V2这两个景点之间的一条路径
void delsucc(MTGraph &G,int v1,int v2){if(!isEdge(G,v1,v2)){cout<<G.verlist[v1]<<"和"<<G.verlist[v2]<<"这两个景点之间不存在路径,不需要在删除路径!"<<endl;return;}int temp=G.edge[v1][v2];G.e--;G.edge[v1][v2]=INF;G.edge[v2][v1]=INF; //G.edge[v1][v2]=0;//G.edge[v2][v1]=0; cout<<"成功删除"<<G.verlist[v1]<<"和"<<G.verlist[v2]<<"这两个景点之间一条长度为"<<temp<<"的路径"<<endl;
}

在main()函数中对应着case 6:

case 6://int v1,v2;cout<<"请输入想要删除路径的景点的编号:"<<endl;cin>>v1>>v2;//删除V1->V2的和V2->V1的边;删除V1和V2这两个景点之间的一条路径delsucc(g,v1,v2);break;

8.增添一个景点;

//创建一个新的顶点 ,并且为这个新顶点设置编号为G.n
void newnode(MTGraph &G,vertexdata v){G.verlist[G.n]=v;//G.n=11G.n++;//G.n=12for(int i=0;i<G.n+1;i++){//i<12  (i:0~11)G.edge[G.n-1][i]=INF;G.edge[i][G.n-1]=INF;}
}

在main()函数中对应着case 7:

case 7://要改进 //string temp;cout<<"请输入想要增添的景点的名称:";cin>>temp;newnode(g,temp); cout<<"成功增添景点:"<<temp<<"  ";cout<<"该景点的编号为:"<<g.n-1<<endl;break;

9.去除一个景点;

//删除一个顶点
void delnode(MTGraph &G,int v){int i,j;for(i=0;i<G.n;i++)if(G.edge[v][i]!=INF){G.edge[v][i]=INF;G.edge[i][v]=INF;  G.e==G.e-2;}// 删除一个顶点 之后表示该图的邻接矩阵 也会改变 for(i=v+1;i<G.n;i++)//行 for(j=0;j<G.n;j++)//列 G.edge[i-1][j]=G.edge[i][j];   for(i=v+1;i<G.n;i++)//列 for(j=0;j<G.n-1;j++)//行 G.edge[j][i-1]=G.edge[j][i];for(i=v+1;i<G.n;i++)G.verlist[i-1]=G.verlist[i];G.n--;
}

在main()函数中对应着case 8:

case 8://删除顶点之后,其他顶点的编号会改变 //int v;//string temp;temp=g.verlist[v];cout<<"请输入想要去除的景点的编号:";cin>>v;  delnode(g,v);cout<<"成功去除景点:"<<temp<<"  ";cout<<"该景点原来的编号为:"<<v<<endl;break;

10.更改景点的简介;

//更改景点的简介
void ch (MTGraph &g,int v,vertexdata temp){g.info[v]=temp;
}

在main()函数中对应着case 9:

case 9://int v;cout<<"请输入想要更改简介的景点的编号:";cin>>v;    temp1=g.verlist[v];cout<<"请输入想要设置的新简介:";cin>>temp;ch (g,v,temp); cout<<"成功将景点:"<<temp1<<"的简介改为:"<<temp<<endl;break;

至此,10个功能都已实现。
运行截图:










这个程序是我学习计算机以来感觉最有趣的一个,完成它我确实费了不少周折,有几个功能的实现对现在的我来说着实烧脑,但越是困难我越是想把它做出来,也正是这些困难,将我通过努力获得成功时的快乐放大了。

学校的校园景点平面图(校园景点迷你地图C++数据结构)相关推荐

  1. 学校的校园景点平面图(校园景点迷你地图C++数据结构)(查询图中顶点间的最短路径查询图中任意两个顶点间的所有路径)

    学校的校园景点平面图(校园景点迷你地图C++&数据结构) 设计要求: (1)建图 以图中顶点表示主要景点,并存放景点的编号.名称.简介等信息: (2)查询 该系统可以查询景点的信息: 查询图中 ...

  2. 【实训大作业】应用无向网表现学校的校园景点平面图

    前言 该作业为学校创新实践基础实训的大作业,因为当时安排在了考试周时间紧张,所以做的比较简陋,基本功能全部实现了,还有一个小bug没改,最后因为里面算法写的不错被打了优秀,放出来给学弟学妹们借鉴了. ...

  3. 垂杨柳中学2021年高考成绩查询时间,实力入选!朝阳这几所学校上榜啦丨校园直通车(2021年第4期)...

    (来源:北京朝阳教育) 原标题:实力入选!朝阳这几所学校上榜啦丨校园直通车(2021年第4期) 上榜单位 北京市陈经纶中学嘉铭分校 北京市第八十中学嘉源分校 北京市朝阳区垂杨柳中心小学金都分校 北京市 ...

  4. 计算机房属于学校场馆吗,小学智慧校园建设方案详细

    建设容: 网络环境建设 1.有线网络 功能描述:校园主干网万兆,千兆到桌面.是校园多媒体教学.校园服务.校园管理.综合安防.有线电视.电子公告屏.校园宣传系统.校园广播等各系统模块正常运转的基本保障. ...

  5. Java图结构-模拟校园地图-迪杰斯特拉(Dijkstra)算法求最短路径 #谭子

    目录目录 一.前言 二.模拟校园地图描述 三.分析题目及相关绘图 四.代码部分 1.GraphNode类 2.Menu类(管理文字) 3.Attraction类 4.AttractionGraph类( ...

  6. c语言 校园导游系统,校园导游系统

    <校园导游系统>由会员分享,可在线阅读,更多相关<校园导游系统(9页珍藏版)>请在人人文库网上搜索. 1.校园导游系统问题说明设计为来访客人提供多种信息查询服务的校园导游计划基 ...

  7. c语言数据结构校园导游系统,校园导游系统课程设计报告

    校园导游系统课程设计报告 目录 1.需求分析1 2.总体设计1 2.1 抽象数据类型图的定义1 2.2 程序中包含的模块1 2.3模块间的调用关系3 3.详细设计3 3.1 代码设计3 3.1.1 定 ...

  8. 【鸿蒙】《校园通》--校园生活模块

    1.校园生活 从上一篇博客[鸿蒙]鸿蒙App应用-<校园通>开发步骤中,点击主页面中的校园生活,进入以下界面,如图一 图1 1.基本步骤 1.创建布局 在layout文件夹下创建布局文件, ...

  9. java毕业设计校园互助平台校园帮帮网站源码+lw文档+mybatis+系统+mysql数据库+调试

    java毕业设计校园互助平台校园帮帮网站源码+lw文档+mybatis+系统+mysql数据库+调试 java毕业设计校园互助平台校园帮帮网站源码+lw文档+mybatis+系统+mysql数据库+调 ...

最新文章

  1. 如何识别 Linux 上的文件分身
  2. android 人生日历,android版人生日历日子怎么用 安卓版人生日历日子使用教程
  3. Python 常用函数time.strftime()简介
  4. 微信公众平台开发--微信网页授权
  5. SQL基础【十八、事物】(sql事物慎用,还是写业务逻辑代码好一些,入伙涉及到更换数据啥的很麻烦!)
  6. keychain 的学习
  7. boid模型的Matlab程序,基于Boid模型以及吸引—排斥模型的沙丁鱼集群运动行为模拟...
  8. How to build .apk file from command line
  9. tp5.0 根据经纬度 获取附近信息_Redis怎么实现查找附近的人之数据类型Geospatial...
  10. 华为性格面试的技巧方法
  11. 鱼眼摄像机弊端及应用
  12. 代码远程调用aria2实现URL资源或BT种子下载
  13. 解决 Word 中空格下划线居中后下划线不显示的问题
  14. vue 验证公民身份证号 并 自动 获取 性别、年龄、生日
  15. 基于OpenCv的视频流处理方法
  16. 面向对象之猫抓老鼠小游戏
  17. 技术一般的程序员找工作,如今真的一年比一年难...
  18. Cognos问题解决
  19. 三维重建、视觉定位、传感器位置推算,滴滴 AR 实景导航技术详解
  20. 王小川如愿远离周鸿祎,他说未来搜索,三分天下

热门文章

  1. 影视剪辑,什么是蒙太奇,蒙太奇的含义
  2. 全球各国as自治系统总数排名、全球自治系统总数排名
  3. 【LeetCode】我能赢吗 [M](记忆化搜索)
  4. 在SecureCRT使用sz与rz命令上传、下载文件命令介绍
  5. 面对新时代挑战,2019维谛技术峰会全面呈献硬核策略
  6. 链上天眼Pro2.0正式上线
  7. mysql js 命令行登录_MYSQL常用命令
  8. 中兴c300 OLT配置SFU
  9. 基金定投:100%抄到底的方法
  10. linux添加fcitx输入法,Ubuntu下轻松安装FCITX输入法