• 数据结构之图的基本操作-校园导游


    数据结构之图的基本操作-校园导游

     

    1.实验题目

          分别用邻接矩阵和邻接表实现以下操作:图的创建、遍历、插入、删除、最短路径。参考题目为校园导游程序

    2.需求分析

          设图的结点不超过 30 个,每个结点用一个编号表示(如果一个图有 n 个结点,则它们 的编号分别为 1,2,…,n)。通过输入图的全部边输入一个图,每个边为一个数对,可以对边 的输入顺序作出某种限制。注意,生成树的边是有向边,端点顺序不能颠倒。

    3.概要设计

          1)为了实现上述程序功能,需要定义单链表的抽象数据类型:

     1   typedef struct ArcCell{
     2 
     3     int adj;
     4 
     5 }ArcCell;//定义边的类型
     6 
     7 typedef struct VertexType{
     8 
     9     int number;
    10 
    11     char *sight;
    12 
    13     char *info;
    14 
    15 }VertexType;//定义定点类型
    16 
    17  
    18 
    19 typedef struct MGraph{
    20 
    21     VertexType vex[NUM]; 
    22 
    23 ArcCell arc[NUM][NUM];
    24 
    25 int vexnum,arcnum;
    26 
    27 }MGraph;//定义图的类型

          2)本程序包含 8 个函数:

               ① 主函数main()

               ② 主菜单函数 Menu()

               ③ 图函数Create(int v,int a)

               ④ 显示景点列表函数 List()

               ⑤  计算最短路径函数 Path()

               ⑥  输出函数 Output()

               ⑦ 哈密尔顿图遍历函数 HaMiTonian() 

               ⑧ 其他函数:NextValue(int k);display().

    4.详细设计

          实现概要设计中定义的所有的数据类型,对每个操作给出伪码算法。对主程序和其他模 块也都需要写出伪码算法。

       • 结点类型和指针类型

     1 typedef struct ArcCell{
     2 
     3 int adj;
     4 
     5 }ArcCell;//定义边的类型
     6 
     7 typedef struct VertexType{
     8 
     9 int number;
    10 
    11 char *sight;
    12 
    13 char *info;
    14 
    15 }VertexType;//定义定点类型
    16 
    17  
    18 
    19 typedef struct MGraph{
    20 
    21 VertexType vex[NUM]; 
    22 
    23 ArcCell arc[NUM][NUM];
    24 
    25 int vexnum,arcnum;
    26 
    27 }MGraph;//定义图的类型

       • 其他模块伪码算法

              主函数main()

              利用各子函数完成对景点的查询及景点间最短路径和长度的查询。

              主菜单函数 Menu()

              利用List()函数完成景点列表的输出及菜单的显示。

              图函数Create(int v,int a)

              利用结构体VertexType初始化景点及其景点描述。

              利用结构体 MGraph规定景点间的距离。

              显示景点列表函数 List()

              利用循环函数输出景点列表。

              计算最短路径函数 Path()

              利用迪杰斯特拉算法计算最短路径。

              哈密尔顿图遍历函数 HaMiTonian() 

              遍历哈密尔顿图。

    5.调试分析

          用无向网表示学校的校园景点平面图,图中顶点表示主要景点,存放景点的编号,名称,简介等信息,图中的边表示景点间的道路,存放长度等信息,要求能回答有关景点介绍,游览路径等问题。游客可询问:从某一景点到另一景点的最短路径。

    6.使用说明

          根据此校园导游程序,可看到所有景点名称。依据提示键入所要进行的操作:1、查询景点之间的路径  2、查询景点信息  0、退出。

          若要进行景点之间路经查询:首先键入“1”,之后根据提示,键入起点编号、终点编号,即可查询最短路径,以及最短路径的距离。

          若要进行景点信息查询:首先键入“2”,之后根据提示,键入所要查询的景点编号,即可查询景点信息。

          键入“0”即退出导游系统。

    7.测试结果

           

          

           

    8.附代码

      1 // 实验四.cpp : 定义控制台应用程序的入口点。
      2 //
      3 
      4 #include "stdafx.h"
      5 #include<stdio.h>
      6 #include<string.h>
      7 #include<malloc.h>
      8 #include<stdlib.h>
      9 #define Max 10000
     10 #define NUM 27
     11 typedef struct ArcCell{
     12     int adj;//相邻两景点的距离
     13 }ArcCell;//定义边的类型
     14 
     15 typedef struct VertexType{
     16     int number;//景点编号
     17     char *sight;//景点名称
     18     char *info;//景点描述
     19 }VertexType;//定义定点类型
     20 
     21 typedef struct MGraph{
     22     VertexType vex[NUM];  //图中顶点,即为景点
     23     ArcCell arc[NUM][NUM];//图中的边,即景点间的距离
     24     int vexnum,arcnum;//顶点数,边数
     25 }MGraph;//定义图的类型
     26 
     27 MGraph G;//定义图为全局变量
     28 int P[NUM][NUM]; 
     29 long int D[NUM];//辅助变量存储最短路径长度
     30 int x[26]={0};
     31 void Create(int v,int a);//图函数
     32 void List();//列表函数
     33 void Path(int num);//最短路径函数
     34 void Output(int sight1,int sight2);//输出函数
     35 char Menu();//主菜单
     36 void HaMiTonian(int);//哈密尔顿图的遍历
     37 void NextValue(int);
     38 void display();//显示遍历结果
     39 
     40 void main()
     41 {
     42     int v0,v1;
     43     int i,num;
     44     char flag; 
     45     Create(NUM,11);
     46     do
     47     {
     48         flag=Menu();
     49         switch(flag)
     50         {
     51         case'1':
     52             system("cls");//执行系统命令,清楚先前屏幕显示的内容
     53             List();//输出景点列表 
     54             printf("
    
    	请选择起点(0~26):");
     55             scanf("%d",&v0);
     56             printf("	请选择终点(0~26):");
     57             scanf("%d",&v1); Path(v0);//计算两个景点之间的最短路径
     58             Output(v0,v1);//输出结果 
     59             printf("
    
    	请按任意键继续...
    ");
     60             getchar();//利用getchar()函数让程序运行到上一行时,等待按下下一个键才返回
     61             getchar();
     62             break;
     63         case'2':
     64             system("cls");
     65             List();//输出景点列表
     66             printf("
    
    	请输入您要查找的景点编号:");
     67             scanf("%d",&num);
     68             for(i=0;i<NUM;i++)
     69             { 
     70                 if(num==G.vex[i].number)
     71                 { 
     72                     printf("
    
    	您要查找景点信息如下:");
     73                     printf("
    
    	%s:",G.vex[i].sight);
     74                     printf("	%s
    
    ",G.vex[i].info);
     75                     printf("
    	按任意键返回...");
     76                     getchar();
     77                     getchar();
     78                     break;
     79                 }
     80             }
     81             if(i==NUM)
     82             {
     83                 printf("
    
    	没有找到!");
     84                 printf("
    
    	按任意键返回...");
     85                 getchar();
     86                 getchar();
     87             } 
     88             break;
     89         }
     90         }while(flag!='0');
     91 } 
     92 char Menu()//主菜单
     93 {
     94     char c;
     95     int flag;
     96     do{
     97         flag=1;
     98         system("cls");
     99         List();//输出景点列表 
    100 
    101         printf("			*************************************
    ");
    102         printf("			           1、查询景点路径           
    ");
    103         printf("			           2、查询景点信息           
    ");
    104         printf("			           0、退出                   
    ");
    105         printf("			*************************************
    ");
    106         printf("	请输入您的选择:");
    107         scanf("%c",&c);
    108         if(c=='1'||c=='2'||c=='0')
    109             flag=0;
    110     }while(flag);
    111     return c;
    112 } 
    113  void Create(int v,int a)//创建图函数
    114  {
    115      int i,j;
    116      G.vexnum=v;//初始化结构中的景点数和边数 
    117      G.arcnum=a; 
    118      for(i=0;i<G.vexnum;++i)
    119          G.vex[i].number=i;//初始化每一个景点的编号
    120      //初始化没一个景点名及其景点描述
    121      G.vex[0].sight="&&&大学正门";
    122      G.vex[0].info="&&&大学正门正门是石家庄铁道大学最大的标志,也是&&&大学的交通关键";
    123      G.vex[1].sight="第一教学楼"; 
    124      G.vex[1].info="走进&&&大学正门即为一个教学楼,是学生们上课、学习的场地";
    125      G.vex[2].sight="第二教学楼";
    126      G.vex[2].info="位于第一教学楼西面,供学生们上课学习";
    127      G.vex[3].sight="大礼堂";
    128      G.vex[3].info="学校在此举行重要典礼以及各学院各社团的迎新晚会";
    129      G.vex[4].sight="春晖楼";
    130      G.vex[4].info="学生处和教务处的办公所在地";
    131      G.vex[5].sight="图书馆"; 
    132      G.vex[5].info="图书馆内设有海量图书,开拓学生视野,可供学生自习。";
    133      G.vex[6].sight="留学生公寓";
    134      G.vex[6].info="国外留学生生活所在地";
    135      G.vex[7].sight="西操";
    136      G.vex[7].info="学校在此举办运动会、升国旗仪式、大型迎新晚会";
    137      G.vex[8].sight="工程训练中心";
    138      G.vex[8].info="学生们进行工程训练的地方";
    139      G.vex[9].sight="第三教学楼"; 
    140      G.vex[9].info="位于第二教学楼北面,供学生们上课学习";
    141      G.vex[10].sight="体育馆";
    142      G.vex[10].info="学生们在此进行体育锻炼";
    143      G.vex[11].sight="地下超市";
    144      G.vex[11].info="提供各种生活学习用品,为学生提供便利";
    145      G.vex[12].sight="综合服务中心";
    146      G.vex[12].info="综合服务中心,为学生提供综合性服务";
    147      G.vex[13].sight="土木实验楼"; 
    148      G.vex[13].info="土木工程学生自习楼和土木学院老师办公楼";
    149      G.vex[14].sight="信息实验楼"; 
    150      G.vex[14].info="信息学院老师办公区";
    151      G.vex[15].sight="第九实验楼";
    152      G.vex[15].info="公共实验楼,设有机房";
    153      G.vex[16].sight="校医院"; 
    154      G.vex[16].info="学生医疗场所";
    155      G.vex[17].sight="基础教学楼";
    156      G.vex[17].info="目前学校设备最齐全的教学楼";
    157      G.vex[18].sight="学生公寓";
    158      G.vex[18].info="学生们休息的地方";
    159      G.vex[19].sight="综合餐厅"; 
    160      G.vex[19].info="学校餐厅,供学生们吃饭";
    161      G.vex[20].sight="毛主席雕像";
    162      G.vex[20].info="这里举行日常升国旗仪式";
    163      G.vex[21].sight="第二食堂";
    164      G.vex[21].info="学生吃饭的地方";
    165      G.vex[22].sight="第一食堂"; 
    166      G.vex[22].info="学生吃饭的地方";
    167      G.vex[23].sight="大时钟";
    168      G.vex[23].info="学校又一标志性建筑,每天上课的钟声从这里响起";
    169      G.vex[24].sight="翠园"; 
    170      G.vex[24].info="公共区域";
    171      G.vex[25].sight="信园"; 
    172      G.vex[25].info="内设打印店,水果摊";
    173      G.vex[26].sight="&&&大学小门"; 
    174      G.vex[26].info="又一学生进出学校的门口";
    175       G.vex[27].sight="干休所"; 
    176      G.vex[27].info="教师公寓";
    177      //这里把所有的边假定为10000,含义是这两个景点之间是不可到达
    178      for(i=0;i<G.vexnum;++i)
    179          for(j=0;j<G.vexnum;++j)
    180            G.arc[i][j].adj=Max;
    181      //下边是可直接到达的景点间的距离,由于两个景点间距离是互相的,所以要对图中对称的边同时赋值
    182      //上面列举并非全部景点
    183      G.arc[0][1].adj=G.arc[1][0].adj=23;
    184      G.arc[1][2].adj=G.arc[2][1].adj=41;
    185      G.arc[1][6].adj=G.arc[6][1].adj=98;
    186      G.arc[1][6].adj=G.arc[4][1].adj=70;
    187      G.arc[2][8].adj=G.arc[8][2].adj=50;
    188      G.arc[2][9].adj=G.arc[9][2].adj=16;
    189      G.arc[2][23].adj=G.arc[23][2].adj=90;
    190      G.arc[3][6].adj=G.arc[6][3].adj=112;
    191      G.arc[3][17].adj=G.arc[17][3].adj=50;
    192      G.arc[3][18].adj=G.arc[18][3].adj=45;
    193      G.arc[3][20].adj=G.arc[20][3].adj=38;
    194      G.arc[3][4].adj=G.arc[3][4].adj=80;
    195      G.arc[6][16].adj=G.arc[16][6].adj=30;
    196      G.arc[4][19].adj=G.arc[19][4].adj=100;
    197      G.arc[4][20].adj=G.arc[20][4].adj=21;
    198      G.arc[5][7].adj=G.arc[7][5].adj=62;
    199      G.arc[5][8].adj=G.arc[8][5].adj=50;
    200      G.arc[5][10].adj=G.arc[10][5].adj=77;
    201      G.arc[5][23].adj=G.arc[23][5].adj=31;
    202      G.arc[5][17].adj=G.arc[17][5].adj=100;
    203      G.arc[11][15].adj=G.arc[15][11].adj=50;
    204      G.arc[11][12].adj=G.arc[11][12].adj=10;
    205      G.arc[11][17].adj=G.arc[17][11].adj=50;
    206      G.arc[12][15].adj=G.arc[15][12].adj=44;
    207      G.arc[13][12].adj=G.arc[12][13].adj=60;
    208      G.arc[14][15].adj=G.arc[15][14].adj=33;
    209      G.arc[15][13].adj=G.arc[13][15].adj=54;
    210      G.arc[18][19].adj=G.arc[19][18].adj=30;
    211      G.arc[18][20].adj=G.arc[20][18].adj=30;
    212      G.arc[18][21].adj=G.arc[21][18].adj=72;
    213      G.arc[18][22].adj=G.arc[22][18].adj=40;
    214      G.arc[23][24].adj=G.arc[24][23].adj=30;
    215      G.arc[17][25].adj=G.arc[25][17].adj=80;
    216      G.arc[12][25].adj=G.arc[25][12].adj=50;
    217      G.arc[27][22].adj=G.arc[22][27].adj=430;
    218      G.arc[26][27].adj=G.arc[27][26].adj=200;
    219     }
    220 void List()//景点列表函数
    221 { 
    222     int k=0;
    223     printf("
    		---------------------------欢迎使用校园导游程序----------------------------
    ");
    224     printf("
    		---------------------------------------------------------------------------
    ");
    225     printf("				         景点名称       			"); 
    226     printf("
    		---------------------------------------------------------------------------
    ");
    227     for(int i=0;i<NUM;i++)
    228     {
    229         printf("		***		(%2d)%-20s				***
    ",i,G.vex[i].sight);//输出景点列表
    230         k=k+1;
    231     } 
    232     printf("		------------------------------------------------------------------------------
    ");
    233 }
    234 void Path(int num)//迪杰斯特拉算法最短路径函数num为入口点的编号
    235 { 
    236     int v,w,i,t;//i、w和v为计数变量
    237     int final[NUM];
    238     int min;
    239     for(int v=0;v<NUM;v++)
    240     { 
    241         final[v]=0;//假设从顶点num到顶点v没有最短路径
    242         D[v]=G.arc[num][v].adj;//将与之相关的权值放入D中存放
    243         for(w=0;w<NUM;w++)//设置为空路径
    244             P[v][w]=0; if(D[v]<20000)//存在路径
    245         { 
    246             P[v][num]=1;//存在标志置为一
    247             P[v][v]=1;//自身到自身
    248         }
    249     }
    250     D[num]=0;
    251     final[num]=1;//初始化num顶点属于S集合
    252     //开始主循环,每一次求得num到某个顶点的最短路径,并将其加入到S集合 
    253     for(i=0;i<NUM;++i)//其余G.vexnum-1个顶点
    254     {
    255         min=Max;//当前所知离顶点num的最近距离
    256         for(w=0;w<NUM;++w)
    257             if(!final[w])//w顶点在v-s中
    258                 if(D[w]<min)//w顶点离num顶点更近
    259                 {
    260                     v=w;
    261                     min=D[w];
    262                 }
    263                 final[v]=1;//离num顶点更近的v加入到s集合
    264                 for(int w=0;w<NUM;++w)//更新当前最短路径极其距离 
    265                     if(!final[w]&&((min+G.arc[v][w].adj)<D[w]))
    266                     {
    267                         D[w]=min+G.arc[v][w].adj;
    268                         for(int t=0;t<NUM;t++)
    269                             P[w][t]=P[v][t];
    270                             P[w][w]=1;
    271                     }
    272     }
    273 }
    274 void Output(int sight1,int sight2)//输出函数
    275 {
    276     int a,b,c,d,q=0;
    277     a=sight2;//将景点二赋值给a
    278     if(a!=sight1)//如果景点二不和景点一输入重合,则进行...
    279     {
    280         printf("
    	从*%s*到*%s*的最短路径为",G.vex[sight1].sight,G.vex[sight2].sight);//输出提示信息
    281         printf("	(最短距离为:%dm.)
    
    	",D[a]);//输出sight1到sight2的最短路径长度,存放在D[]数组中
    282         printf("	%s",G.vex[sight1].sight);//输出景点一的名称
    283         d=sight1;
    284         //将景点一的编号赋值给d
    285         for(c=0;c<NUM;++c)
    286         {
    287 gate:;//标号,可以作为goto语句跳转的位置
    288             P[a][sight1]=0;
    289             for(b=0;b<NUM;b++)
    290             {
    291                 if(G.arc[d][b].adj<20000&&P[a][b])
    292                 {
    293                     printf("-->%s",G.vex[b].sight);//输出此节点的名称
    294                     q=q+1;//计数变量加一,满8控制输出时的换行
    295                     P[a][b]=0;
    296                     d=b;
    297                     if(q%9==0)printf("
    ");
    298                     goto gate;
    299                 }//if(G.arcs[d][b].adj<20000&&P[a][b])
    300             }    //for(b=0;b<NUM;b++)
    301         }//for(c=0;c<NUM;++c)
    302     }
    303 }
    304 
    305 void HaMiTonian(int m)//哈密尔顿图的遍历
    306 { 
    307     if(m>26)
    308         return; 
    309 L:NextValue(m);//标号,可以作为goto语句跳转的位置 
    310     if(x[m]==0) 
    311         return;
    312     if(m==26&&G.arc[0][x[26]-1].adj!=0000)
    313         display();
    314     else 
    315         HaMiTonian(m+1);
    316     goto L;//使用goto语句改变程序流向,转去执行语句标号L所标识的语句
    317 
    318 }
    319 void NextValue(int k)
    320 {
    321     int j;
    322 l:x[k]=(x[k]+1)%10;//标号,可以作为goto语句跳转的位置
    323     if(x[k]==0)
    324         return;
    325     if(G.arc[x[k-1]-1][x[k]-1].adj!=10000)
    326     {
    327         for(j=0;j<k;j++)
    328             if(x[j]==x[k])
    329                 goto l;
    330                 return;
    331     }
    332     else
    333         goto l;//使用goto语句改变程序流向,转去执行语句标号l所标识的语句
    334 }
    335 
    336 void display()
    337 {
    338     int i=0;
    339     for(i=0;i<26;i++)
    340         printf("%s->",G.vex[x[i]-1].sight);
    341 }
    View Code
  • 相关阅读:
    一次性删除 .svn 文件夹
    vim
    03 练习题:字符串
    04 练习题:元组、列表
    05 练习题:字典
    Python基础学习笔记(07)基础类型操作及转化、编码
    Python基础学习笔记(06)代码块、集合、深浅copy
    Python基础学习笔记(05)字典
    Python基础学习笔记(04)列表、元组
    67.滚轮事件
  • 原文地址:https://www.cnblogs.com/ynly/p/14273268.html
Copyright © 2020-2023  润新知