数据结构实验(四)

1.实验题目

    图是应用极为广泛的数据结构,也是这门课程的重点。它的特点在于非线性。稀疏矩阵 的十字链表存储结构也是图的一种存储结构,故也把它们归在这次实习中。本章实习继续突 出了数据结构加操作的程序设计观点,但根据这两种结构的非线性特点,将操作进一步集中 在遍历操作上,因为遍历操作是其他众多操作的基础。遍历逻辑的(或符号形式的)结构, 访问动作可是任何操作。本次实习还希望达到熟悉各种存储结构的特征,以及如何应用树和 图结构解决具体问题(即原理与应用的结合)等目的。

2.需求分析

分别用邻接矩阵和邻接表实现以下操作:图的创建、遍历、插入、删除、最短路径。

顶点信息边信息的存储,数据结构类型

图的操作 查找,邻接表到有向图

路径输出。判断是否为通路。

图的深度遍历。

3.概要设计

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

    (1)借助于栈类型(自己定义和实现)将深度优先遍历用非递归算法实现。

    (2)以邻接表为存储结构建立深度优先生成树和广度优先生成树,再按凹入表或树形打印生成树。

4.详细设计

 #include<stdio.h>//实验四
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define Max 11
#define MX 999999
int D[Max][Max];
int path[Max][Max];
typedef struct Ver{//顶点信息
    char num[5];
    char name[51];
    char instruct[101];
}Ver;
typedef struct{//邻接矩阵
    Ver vex[Max];//顶点表
    int arcs[Max][Max];
    int vnum,arcnum;
}AMGragh;
void menu(){
    cout<<"************欢迎您************"<<endl;
    cout<<"        1、查看所有景点           "<<endl;
    cout<<"        2、景点查询               "<<endl;
    cout<<"        3、问路                   "<<endl;
    cout<<"        4、修改景点基本信息       "<<endl;
    cout<<"        5、退出                   "<<endl;
    cout<<"**********************************"<<endl;
    cout<<"请选择..."<<endl;
}
void Allprint(AMGragh G){//输出所有景点信息
    cout<<"---------------校园景点总览---------------"<<endl;
    cout<<"景点名称   "<<"  "<<"代号"<<"     "<<"    简介"<<endl;
    for(int i=0;i<G.vnum;i++){
        cout<<G.vex[i].name<<"    "<<G.vex[i].num<<"   "<<G.vex[i].instruct<<endl;
    }
    cout<<endl;
}
void CreateUDG(AMGragh &G){//建图
    G.vnum=10;
    strcpy(G.vex[0].num,"01");
    strcpy(G.vex[1].num,"02");
    strcpy(G.vex[2].num,"03");
    strcpy(G.vex[3].num,"04");
    strcpy(G.vex[4].num,"05");
    strcpy(G.vex[5].num,"06");
    strcpy(G.vex[6].num,"07");
    strcpy(G.vex[7].num,"08");
    strcpy(G.vex[8].num,"09");
    strcpy(G.vex[9].num,"10");
    strcpy(G.vex[0].name,"北苑美食城");
    strcpy(G.vex[1].name,"北操场    ");
    strcpy(G.vex[2].name,"体育馆    ");
    strcpy(G.vex[3].name,"图书馆    ");
    strcpy(G.vex[4].name,"广场1     ");
    strcpy(G.vex[5].name,"广场2     ");
    strcpy(G.vex[6].name,"湿地公园  ");
    strcpy(G.vex[7].name,"公园2     ");
    strcpy(G.vex[8].name,"湖 1      ");
    strcpy(G.vex[9].name,"公园3     ");
    strcpy(G.vex[0].instruct,"北苑美食城里面有各种各样的美食,可以让你大饱口福");
    strcpy(G.vex[1].instruct,"北操场是北苑的一个运动场地,也是一个篮球场");
    strcpy(G.vex[2].instruct,"体育馆设施齐全,建筑优美,在此可以尽情享受运动的快乐!");
    strcpy(G.vex[3].instruct,"图书馆环境安适,藏书丰富,让人感受阅读的美好");
    strcpy(G.vex[4].instruct,"广场1与学校西门相邻,也是升国旗的地方");
    strcpy(G.vex[5].instruct,"广场2上会举办一些文艺晚会和校园招聘会,更是轮滑爱好者的乐园");
    strcpy(G.vex[6].instruct,"湿地公园有小石桥和美丽的树木,让人心旷神怡");
    strcpy(G.vex[7].instruct,"公园2的标志是一对白色的大海豚,坐落在水中央,夏天水中开有漂亮的莲花");
    strcpy(G.vex[8].instruct,"湖 1的水清澈见底,还能看到活泼的小鱼");
    strcpy(G.vex[9].instruct,"公园3里往届校友栽的树,生机勃勃,代表着他们对母校的爱");
    G.arcs[1][2]=G.arcs[2][1]=2;
    G.arcs[1][9]=G.arcs[9][1]=19;
    G.arcs[2][3]=G.arcs[3][2]=3;
    G.arcs[2][4]=G.arcs[4][2]=5;
    G.arcs[3][4]=G.arcs[4][3]=2;
    G.arcs[4][5]=G.arcs[5][4]=3;
    G.arcs[4][7]=G.arcs[7][4]=29;
    G.arcs[4][10]=G.arcs[10][4]=33;
    G.arcs[5][6]=G.arcs[6][5]=6;
    G.arcs[6][7]=G.arcs[7][6]=7;
    G.arcs[7][8]=G.arcs[8][7]=8;
    G.arcs[8][9]=G.arcs[9][8]=1;
    G.arcs[9][10]=G.arcs[10][9]=2;
    for(int i=1;i<=10;i++)//初始化路径长度
        for(int j=1;j<=10;j++){
            if(G.arcs[i][j]==0&&i!=j)
                G.arcs[i][j]=MX;
        }
    G.arcnum=13;
}
void Change(AMGragh &G){//修改信息
    Allprint(G);
    cout<<"请输入要修改信息的代号:";
    char c[5];
    cin>>c;
    for(int i=0;i<G.vnum;i++){
        if(strcmp(c,G.vex[i].num)==0)//字符串比较的方法进行查找
        {
            memset(G.vex[i].name,0,sizeof(G.vex[i].name));
            memset(G.vex[i].num,0,sizeof(G.vex[i].num));
            memset(G.vex[i].instruct,0,sizeof(G.vex[i].instruct));
            char num1[5];
            char name1[51];
            char instruct1[101];
            cout<<"请输入修改后的景点信息:"<<endl;
            cout<<"景点名称:";
            scanf("%s",name1);
            cout<<"代号:";
            scanf("%s",num1);
            cout<<"简介:";
            scanf("%s",instruct1);
            strcpy(G.vex[i].name,name1);
            strcpy(G.vex[i].num,num1);
            strcpy(G.vex[i].instruct,instruct1);
            cout<<"修改成功!"<<endl;
            break;
        }
    }
}
void Query(AMGragh G){//查询景点
    cout<<"请输入查询景点的代号:";
    char c[5];
    cin>>c;
    int i;
    for(i=0;i<G.vnum;i++)
        if(strcmp(c,G.vex[i].num)==0)
        {
            cout<<"景点名称:"<<G.vex[i].name<<"   ";
            cout<<"代号:"<<G.vex[i].num<<"   ";
            cout<<"简介:"<<G.vex[i].instruct<<endl;
            break;
        }
    if(i==G.vnum)
        cout<<"该代号不存在!"<<endl;
}
void Floyd(AMGragh G){//弗洛伊德算法,获得最短路径
    int i,j,k;
    for(i=1;i<=G.vnum;++i)
        for(j=1;j<=G.vnum;j++){
            D[i][j]=G.arcs[i][j];
            if(D[i][j]<MX&&i!=j)
                path[i][j]=i;
            else
                path[i][j]=-1;
        }
    for(k=1;k<=G.vnum;k++)
        for(i=1;i<=G.vnum;++i)
            for(j=1;j<=G.vnum;j++)
                if(D[i][k]+D[k][j]<D[i][j]){
                    D[i][j]=D[i][k]+D[k][j];
                    path[i][j]=path[k][j];
                }
}
void Path(AMGragh G,int a,int b){//获得具体路径
   int p[Max];
   p[0]=b;
   int i=1;
   while(a!=b){
    b=path[a][b];
    p[i]=b;
    ++i;
   }
   cout<<"路径:"<<G.vex[a-1].name;
   i=i-2;
   while(i>=0){
    cout<<"--->"<<G.vex[p[i]-1].name;
    --i;
   }
}
void Ask(AMGragh G){//问路
    Allprint(G);
    cout<<"请输入起点和目的地(1~10,即第几个景点,中间用空格隔开):";
    int a,b;
    cin>>a>>b;
    Floyd(G);
    cout<<endl<<endl<<"从"<<G.vex[a-1].name<<"到"<<G.vex[b-1].name<<":"<<endl<<endl<<"最短路径长度:"<<D[a][b]*10<<"米"<<endl;
    Path(G,a,b);
    cout<<endl;
}
int main(){
    AMGragh G;
    memset(G.arcs,0,sizeof(G.arcs));
    CreateUDG(G);
    int m;
    while(m!=5){
        menu();
        cin>>m;
        switch(m){
        case 1:
            Allprint(G);
            break;
        case 2:
            Query(G);
            break;
        case 3:
            Ask(G);
            break;
        case 4:
            Change(G);
            break;
        case 5:
            cout<<"感谢您的使用!"<<endl;
            return 0;
        default:
            cout<<"没有该选项!"<<endl;
        }
        system("pause");
        system("cls");
    }
    return 0;
}

5.调试分析

     不能重复保留上一个问题,对于最短路径问题是不完全符合实际。所有景点是前期数据保存的,不需要人为的输入。

6.使用说明

  根据菜单栏提示选择要执行程序即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值