c语言数据结构--图综合应用实验——校院导航

news2024/11/15 15:48:14

实验内容:

面向学校,构建一个校院导游软件。用无向图表示所在学校的校院景点平面图,图中顶点表示主要景点,存放景点的编号、名称、简介等信息,图中边表示景点之间的道路,存放路径距离等信息。该软件具有以下基本功能,学生可自行扩展功能。
1)查询各景点的详细信息;
2)查询图中任意两个景点之间的所有可能路径;
3)查新图中任意两个景点之间的最短路径;
4)增加、删除、更新景点与道路信息

实验步骤:

(1)按照实验要求编写代码,构造导游软件系统。
(2)输入验收用例,验证其输出结果。

#include <iostream>
#include<string.h>
using namespace std;
#define MVNum 100
#define MAXDIS 368789

typedef struct ArcNode
{
    double distance;
    ArcNode *nextarc;
    int adjvex;
};
int *visit;
typedef struct VNode
{
    int number;
    string name;
    string resume;
    ArcNode *firstarc;
} VNode,AdjList[MVNum];
struct road
{
    int startPoint;
    int endPoint;
    double distance;
};

struct AGraph
{
    AdjList adjlist;
    double adjmatrix[MVNum][MVNum];
    int vexnum,arcnum;
};

int LocateVex(AGraph G,int v)
{
    for(int i =0; i<G.vexnum; i++)
    {
        if(G.adjlist[i].number==v) return i;
    }
    return -1;
}

void createvisit(int* &visit,int vexnum)
{
    visit = new int[vexnum];
    for(int i = 0; i < vexnum; i++)
    {
        visit[i] = 0;
    }
}

//构建无向图的邻接表
void CreateUDG(AGraph &G)
{
    G.vexnum=7;
    G.arcnum=10;
    createvisit(visit,G.vexnum);
    G.adjlist[0].number=0;
    G.adjlist[0].name="材料重点实验室";
    G.adjlist[0].resume="国家重点实验室";
    G.adjlist[0].firstarc=NULL;
    G.adjlist[1].number=1;
    G.adjlist[1].name="计算机学院";
    G.adjlist[1].resume="计算机上课的地方";
    G.adjlist[1].firstarc=NULL;
    G.adjlist[2].number=2;
    G.adjlist[2].name="志义体育场";
    G.adjlist[2].resume="运动会举办的地方";
    G.adjlist[2].firstarc=NULL;
    G.adjlist[3].number=3;
    G.adjlist[3].name="图书馆";
    G.adjlist[3].resume="河南存储书最多的地方";
    G.adjlist[3].firstarc=NULL;
    G.adjlist[4].number=4;
    G.adjlist[4].name="综合教学楼";
    G.adjlist[4].resume="学校主要上课的地方";
    G.adjlist[4].firstarc=NULL;
    G.adjlist[5].number=5;
    G.adjlist[5].name="物理学院";
    G.adjlist[5].resume="全校物理实验的上课地方";
    G.adjlist[5].firstarc=NULL;
    G.adjlist[6].number=6;
    G.adjlist[6].name="创业中心";
    G.adjlist[6].resume="最受学生喜欢的地方";
    G.adjlist[6].firstarc=NULL;
    //初始化邻接矩阵
    for (int i = 0; i<G.vexnum; i++)
    {
        for(int j = 0; j<G.vexnum; j++)
        {
            G.adjmatrix[i][j]=MAXDIS;
            //  if(i==j) G.adjmatrix[i][j]=0;
        }
    }
    //road1用于最初的图形初始化
    road road1[] = {{0,1,30},{1,3,10},{1,2,20},{1,4,10},{3,5,40},{3,4,5},{4,5,30},{2,4,30},{4,6,5},{5,6,50}};
    for(int k=0; k<G.arcnum; k++)
    {
        int number1,number2;
        double weight;
        number1 = road1[k].startPoint;
        number2 = road1[k].endPoint;
        weight=road1[k].distance;
        //将景点编号转为下标
        int i = LocateVex(G,number1);
        int j = LocateVex(G,number2);
        G.adjmatrix[i][j]=weight;
        G.adjmatrix[j][i]=weight;

        ArcNode *p1 = new ArcNode;
        p1->adjvex =j;
        p1->distance=weight;
        p1->nextarc = G.adjlist[i].firstarc;
        G.adjlist[i].firstarc=p1;

        ArcNode *p2 = new ArcNode;
        p2->distance=weight;
        p2->adjvex=i;
        p2->nextarc=G.adjlist[j].firstarc;
        G.adjlist[j].firstarc=p2;
    }
}
//该算法使用前需要设置一个visit数组,且全部为0,vi是起点,vj是终点
void FindPath(AGraph g,int vi,int vj,int path[],int d)
{
    ArcNode *p;
    visit[vi]=1;
    path[++d]=vi;
    if(vi==vj)
    {
        for(int i = 0; i<=d; i++)
        {
            cout << g.adjlist[path[i]].name<<" ";
        }
        cout << endl;
    }
    p=g.adjlist[vi].firstarc;
    while(p)
    {
        if(visit[p->adjvex]==0) FindPath(g,p->adjvex,vj,path,d);
        p = p->nextarc;
    }
    visit[vi]=0;
}

void Floyd(AGraph g,int path[MVNum][MVNum],int map[MVNum][MVNum])
{
    int n = g.vexnum;
    for(int i=1; i<=g.vexnum; i++)
    {
        for(int j=1; j<=n; j++)
        {
            if(i==j)
                map[i][j]=0;
            else
                map[i][j]=MAXDIS;
        }
    }

    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
            if(g.adjmatrix[i][j]!=MAXDIS)
            {
                map[i+1][j+1]=g.adjmatrix[i][j];
                map[j+1][i+1]=g.adjmatrix[i][j];
                path[i+1][j+1]=j+1;
            }
        }
    }
    //计算最短距离
    for(int k=1; k<=n; k++)
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                if(map[i][k]+map[k][j]<map[i][j])
                {
                    map[i][j]=map[i][k]+map[k][j];
                    path[i][j]=path[i][k];
                }
    int v1,v2,z;
    cout<<"输入两个景点编号,输出最短路径"<<endl;
    cin>>v1>>v2;
    v1=LocateVex(g,v1);
    v2=LocateVex(g,v2);
    if(v1==-1||v2==-1) return;
    v1=v1+1;
    v2=v2+1;
    z=path[v1][v2];
    cout<<g.adjlist[v1-1].name;
    while(z!=v2)
    {
        cout<<"->"<<g.adjlist[z-1].name;
        z=path[z][v2];
    }
    cout<<"->"<<g.adjlist[v2-1].name;
}

void addV(AGraph &g,int n,int vi,int distance){
    cout << "请输入增加顶点的名称以及简介:";
    //邻接表增加
    cin >>g.adjlist[g.vexnum].name;
    cin >> g.adjlist[g.vexnum].resume;
    g.adjlist[g.vexnum].firstarc=NULL;
    g.adjlist[g.vexnum].number=g.adjlist[g.vexnum-1].number+1;
    g.vexnum=g.vexnum+1;//景点数+1
    //边表增加
    cout << endl<<"请输入景点的道路数目:";
    cin >> n;
    g.arcnum=g.arcnum+n;//边数+n
    cout << endl<<"请输入每条道路以该景点为起点所能到达的景点编号以及距离:"<<endl;
    //邻接矩阵初始化
    for(int i = 0; i<g.vexnum; i++)
    {
        g.adjmatrix[g.vexnum-1][i]=MAXDIS;
        g.adjmatrix[i][g.vexnum-1]=MAXDIS;
    }
    //创建边
    for(int i=0; i<n; i++)
    {
        cin >> vi >> distance;
        ArcNode *p1 = new ArcNode;
        p1->adjvex =vi;
        p1->distance=distance;
        p1->nextarc = g.adjlist[g.vexnum-1].firstarc;
        g.adjlist[g.vexnum-1].firstarc=p1;
        g.adjmatrix[g.vexnum-1][vi]=distance;
        g.adjmatrix[vi][g.vexnum-1]=distance;
        ArcNode *p2 = new ArcNode;
        p2->distance=distance;
        p2->adjvex=g.vexnum-1;
        p2->nextarc=g.adjlist[vi].firstarc;
        g.adjlist[vi].firstarc=p2;
    }
    //删除景点
}

void deleteV(int vi,AGraph &g){
    //修改邻接矩阵
    for(int i=vi+1; i<g.vexnum; i++)
    {
        for(int j=0; j<g.vexnum; j++)
        {
            g.adjmatrix[i-1][j]=g.adjmatrix[i][j];
        }
        for(int j=0; j<g.vexnum; j++)
        {
            g.adjmatrix[j][i-1]=g.adjmatrix[j][i];
        }
    }
    //修改邻接表
    for(int i=0; i<g.vexnum; i++)
    {
        //边指针
        ArcNode *p=g.adjlist[i].firstarc;
        //一条边的处理情况
        if(p->nextarc==NULL)
        {
            if(p->adjvex==vi)
            {
                g.adjlist[i].firstarc=NULL;
                g.arcnum=g.arcnum-1;
            }
        }
        //没有边
        else if(p==NULL) continue;
        //多条边
        else
        {
            //如果是首元结点
            if(p->adjvex==vi)
            {
                g.adjlist[i].firstarc=p->nextarc;
                g.arcnum=g.arcnum-1;
                continue;
            }
            //不是首元结点
            while(p->nextarc&&p->nextarc->adjvex!=vi)
            {
                p=p->nextarc;
            }
            if(p->nextarc)
            {
                p->nextarc=p->nextarc->nextarc;
                g.arcnum=g.arcnum-1;
            }
        }
    }
    for(int i=vi; i<g.vexnum-1; i++)
    {
        g.adjlist[i]=g.adjlist[i+1];
    }
    g.vexnum=g.vexnum-1;
}

void show(AGraph g){
    for(int i = 0; i <g.vexnum; i++)
    {
        cout << "编号:"<<g.adjlist[i].number<<"\t名称:"<<g.adjlist[i].name<<"\t简介:"<<g.adjlist[i].resume<<endl;
    }
}

void addPath(AGraph &g,int vi,int vj,int distance){
    cout << "请输入该路径长度:"<<endl;
    cin >> distance;
    g.adjmatrix[vi][vj]=distance;
    g.adjmatrix[vj][vi]=distance;

    ArcNode *p1 = new ArcNode;
    p1->adjvex =vj;
    p1->distance=distance;
    p1->nextarc = g.adjlist[vi].firstarc;
    g.adjlist[vi].firstarc=p1;

    ArcNode *p2 = new ArcNode;
    p2->distance=distance;
    p2->adjvex=vi;
    p2->nextarc=g.adjlist[vj].firstarc;
    g.adjlist[vj].firstarc=p2;
    g.arcnum=g.arcnum+1;
}

void alterV(int vi,AGraph &g){
    cout << "请输入要修改的景点编号:";
    cin >> vi;
    vi = LocateVex(g,vi);
    cout << "请输入修改后的景点名称以及简介:";
    cin >> g.adjlist[vi].name;
    cin >> g.adjlist[vi].resume;
}

void deletePath(AGraph &g,int vi,int vj){
            g.adjmatrix[vi][vj]=MAXDIS;
            g.adjmatrix[vj][vi]=MAXDIS;
            ArcNode *p=g.adjlist[vi].firstarc;
            //一条边的处理情况
            if(p->nextarc==NULL)
            {
                if(p->adjvex==vj)
                {
                    g.adjlist[vi].firstarc=NULL;
                    g.arcnum=g.arcnum-1;
                }
            }
            //多条边
            else
            {
                //如果是首元结点
                if(p->adjvex==vj)
                {
                    g.adjlist[vi].firstarc=p->nextarc;
                    g.arcnum=g.arcnum-1;
                }
                //不是首元结点
                while(p->nextarc&&p->nextarc->adjvex!=vj)
                {
                    p=p->nextarc;
                }
                if(p->nextarc)
                {
                    p->nextarc=p->nextarc->nextarc;
                    g.arcnum=g.arcnum-1;
                }
            }
            p=g.adjlist[vj].firstarc;
            //一条边的处理情况
            if(p->nextarc==NULL)
            {
                if(p->adjvex==vi)
                {
                    g.adjlist[vj].firstarc=NULL;
                    g.arcnum=g.arcnum-1;
                }
            }
            //多条边
            else
            {
                //如果是首元结点
                if(p->adjvex==vi)
                {
                    g.adjlist[vj].firstarc=p->nextarc;
                    g.arcnum=g.arcnum-1;
                }
                //不是首元结点
                while(p->nextarc&&p->nextarc->adjvex!=vi)
                {
                    p=p->nextarc;
                }
                if(p->nextarc)
                {
                    p->nextarc=p->nextarc->nextarc;
                    g.arcnum=g.arcnum-1;
                }
            }
}

void alterPath(AGraph &g,int distance,int vi,int vj){
    cout << "请输入修改后的路径长度"<<endl;
    cin >> distance;
    g.adjmatrix[vi][vj]=distance;
    g.adjmatrix[vj][vi]=distance;
    ArcNode *p=g.adjlist[vi].firstarc;
    while(p->adjvex!=vj) p=p->nextarc;
    p->distance=distance;
    p=g.adjlist[vj].firstarc;
    while(p->adjvex==vi) p=p->nextarc;
    p->distance=distance;
}

void home()
{
    cout <<" |   <河南大学校园导航>   |"<<endl;
    cout <<" |    1.校园景点          |"<<endl;
    cout <<" |    2.查询路径          |"<<endl;
    cout <<" |    3.最短路径          |"<<endl;
    cout <<" |    4.增加景点          |"<<endl;
    cout <<" |    5.删除景点          |"<<endl;
    cout <<" |    6.修改景点          |"<<endl;
    cout <<" |    7.增加路径          |"<<endl;
    cout <<" |    8.删除路径          |"<<endl;
    cout <<" |    9.修改路径          |"<<endl;
    cout <<" |    10.退出导航         |"<<endl;
}
int main()
{
    AGraph g;
    CreateUDG(g);
    int path[g.vexnum];
    int path1[MVNum][MVNum];
    int map[MVNum][MVNum];
    int vi,vj;
    int distance;
    int choice;
    int n;
    home();
    while(1)
    {
        cout << "请输入您的需求:";
        cin >> choice;
        switch(choice)
        {
        case 1:
            //查询各景点信息
            show(g);
            break;
        //查询任意路径
        case 2:
            cout << "请依次输入初始景点编号及终点景点编号:";
            cin >> vi >> vj;
            vi = LocateVex(g,vi);
            vj = LocateVex(g,vj);
            if(vi==-1||vj==-1) break;
            cout << endl;
            FindPath(g,vi,vj,path,-1);
            break;
        //最短路径
        case 3:
            Floyd(g,path1,map);
            cout << endl;
            break;
        //增加景点
        case 4:
            addV(g,n,vi,distance);
            break;
        case 5:
            cout << "请输入景点编号:";
            cin >> vi;
            vi = LocateVex(g,vi);
            if(vi==-1) break;
            deleteV(vi,g);
            break;
        //修改景点
        case 6:
            alterV(vi,g);
            break;
        //增加路径
        case 7:
        {
            cout << "请输入路径两端景点编号:"<<endl;
            cin >>vi >> vj;
            vi = LocateVex(g,vi);
            vj = LocateVex(g,vj);
            if(vi==-1||vj==-1) break;
            addPath(g,vi,vj,distance);
        }
            break;
        //删除路径
        case 8:
            cout << "请输入路径两端景点编号:"<<endl;
            cin >>vi >> vj;
            vi = LocateVex(g,vi);
            vj = LocateVex(g,vj);
            if(vi==-1||vj==-1) break;
            deletePath(g,vi,vj);
            break;
        case 9:
            cout << "请输入路径两端景点编号:"<<endl;
            cin >>vi >> vj;
            vi = LocateVex(g,vi);
            vj = LocateVex(g,vj);
            if(vi==-1||vj==-1) break;
            alterPath(g,distance,vi,vj);
            break;
        case 10:
            return 0;
            break;

            }
            cout <<endl;
    }
    return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1915197.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

dledger原理源码分析(四)-日志

简介 dledger是openmessaging的一个组件&#xff0c; raft算法实现&#xff0c;用于分布式日志&#xff0c;本系列分析dledger如何实现raft概念&#xff0c;以及dledger在rocketmq的应用 本系列使用dledger v0.40 本文分析dledger的日志&#xff0c;包括写入&#xff0c;复制…

软件架构之架构风格

软件架构之架构风格 9.3 软件架构风格9.3.1 软件架构风格分类9.3.2 数据流风格9.3.3 调用/返回风格9.3.4 独立构件风格9.3.5 虚拟机风格9.3.6 仓库风格 9.4 层次系统架构风格9.4.1 二层及三层 C/S 架构风格9.4.2 B/S 架构风格9.4.3 MVC 架构风格9.4.4 MVP 架构风格 9.5 面向服务…

力扣 双指针基础

class Solution {public void moveZeroes(int[] nums) {int l 0;//慢指针但先走for (int r 0; r < nums.length; r) {//快指针&#xff0c;遍历次数if (nums[r] 0) continue;//l比r先到&#xff0c;在此处定住l&#xff0c;r继续移动int t nums[l];nums[l] nums[r];num…

上交发布MG-LLaVA,基于多粒度指令调整,横扫视觉大模型榜单

近年来多模态大语言模型(MLLMs)在视觉理解任务中取得了长足进步。然而&#xff0c;大多数模型仍局限于处理低分辨率图像&#xff0c;这限制了它们在需要详细视觉信息的任务中的表现。针对这一问题&#xff0c;上海交通大学的研究团队推出了MG-LLaVA&#xff08;Multi-Granulari…

Animate软件基础:重命名图层或文件夹

默认情况下&#xff0c;Animate 会按照创建顺序向新图层分配名称&#xff1a;图层 1、图层 2&#xff0c;依此类推。为了更好地反映图层的内容&#xff0c;可以对图层进行重命名。 如果需要对图层或图层文件夹进行重命名&#xff0c;请执行下列操作之一&#xff1a; 双击时间轴…

二叉平衡树(左单旋,右单旋,左右双旋、右左双旋)

一、AVL树&#xff08;二叉平衡树&#xff1a;高度平衡的二叉搜索树&#xff09; 0、二叉平衡树 左右子树高度差不超过1的二叉搜索树。 public class AVLTree{static class AVLTreeNode {public TreeNode left null; // 节点的左孩子public TreeNode right null; // 节点的…

MySQL之基本查询(上)-表的增删查改

目录 Create(创建) 案例建表 插入 单行数据 指定列插入 单行数据 全列插入 多行数据 全列插入 插入是否更新 插入时更新 替换 Retrieve(读取) 建表插入 select列 全列查询 指定列查询 查询字段为表达式 为查询结果指定别名 结果去重 where条件 比较运算符 逻辑运…

【UE5.1 角色练习】16-枪械射击——瞄准

目录 效果 步骤 一、瞄准时拉近摄像机位置 二、瞄准偏移 三、向指定方向射击 四、连发 效果 步骤 一、瞄准时拉近摄像机位置 打开角色蓝图&#xff0c;在事件图表中添加如下节点&#xff0c;当进入射击状态时设置目标臂长度为300&#xff0c;从而拉近视角。 但是这样切…

数学建模中常用的数据处理方法

常用的数据处理方法 本文参考 B站西电数模协会的讲解视频 &#xff0c;只作笔记提纲&#xff0c;想要详细学习具体内容请观看 up 的学习视频。国赛的 C 题一般数据量比较大。 这里介绍以下两种方法&#xff1a; 数据预处理方法 数据分析方法 数据预处理方法 1. 数据清洗 为…

【后端开发实习】用MongoDB实现仓库管理的出库入库实战

用MongoDB实现仓库管理的出库入库 MongoDB什么是MongoDBMongoDB安装以及开始运行配置启动以及mongoshmongodb的基础使用命令启动和使用MongoDB服务数据库操作集合操作文档操作 项目部署在数据库中创建一张商品信息表提供信息表的增删改查操作接口 MongoDB 什么是MongoDB Mong…

德语中含“Augen”的惯用语表达-柯桥小语种学习德语考级

在我们的德语学习过程中&#xff0c;除了词汇的记忆&#xff0c;另一项重要的记忆任务就是惯用语的背诵啦。要知道&#xff0c;德语中有大量的Redewendung&#xff0c;他们以其言简意赅的表达&#xff0c;在日常用语中备受青睐。上一期我们已经学习了部分含有“Hand”的惯用语&…

每日一题~abc356(对于一串连续数字 找规律)

添加链接描述 题意&#xff1a;对于给定的n,m 。计算0~n 每一个数和m & 之后&#xff0c;得到的数 的二进制中 1的个数的和。 一位一位的算。最多是60位。 我们只需要计算 在 1-n这些数上&#xff0c;有多少个数 第i位 为1. 因为是连续的自然数&#xff0c;每一位上1 的…

ARM学习(29)NXP 双coreMCU IMX1160学习----NorFlash 启动引脚选择

ARM学习&#xff08;28&#xff09;NXP 双coreMCU IMX1160学习----NorFlash 启动引脚选择 1、多种启动方式介绍 IMX1166 支持多组flexSPI 引脚启动&#xff0c;FlexSPI1以及FlexSPI2&#xff0c;通过boot cfg可以切换FlexSPI得实例。 每个实例又支持多组引脚&#xff0c;总共…

Let‘s Encrypt性价比最高的申请SSL证书

SSL/TLS证书作为确保网站数据传输安全性的重要手段&#xff0c;受到了广大网站运营者的青睐。然而&#xff0c;高昂的证书费用往往成为许多小型网站和个人博客的负担。 申请Lets Encrypt免费泛域名SSL证书步骤 1. 登录来此加密网站&#xff0c;输入域名&#xff0c;可以勾选泛…

食物链之带权并查集解法

直接看题&#xff1a;https://www.acwing.com/problem/content/description/242/ 下面就是代码的实现了&#xff0c;因为自己与自己肯定是同类我们初始化为0. 下面是AC代码&#xff1a; #include<bits/stdc.h> using namespace std; int n,k; int fk,x,y; int fa[10001…

染色法判定二分图

什么是二分图&#xff1f; 二分图&#xff0c;也称作二部图&#xff0c;是图论中的一种特殊模型。在一个无向图G(V,E) 中&#xff0c;如果顶点集合 V 可以被分割成两个互不相交的子集 A 和 B&#xff0c;并且图中的每条边 (i,j) 关联的两个顶点 i 和 j 分别属于这两个不同的顶…

第三课网关作用

实验拓扑图&#xff1a; 基础配置&#xff1a; PC1的基础配置 PC2的基础配置&#xff1a; PC4的基础配置 AR1添加PC4网段: 并且添加pc1,pc2的网段。 并且添加pc1,pc2的网段。 原理&#xff1a;PC4先把数据交给100.100.100.1&#xff0c;交给了路由器&#xff0c;路由器再把数…

分贝通差旅管理费控BI 助力企业差旅报销降本

在企业的日常运营中&#xff0c;每张机票、每个酒店预订、每次用车、每笔对公付款&#xff0c;这些看似零碎的支出累积起来&#xff0c;每月往往能轻松达到数百万元。面对如此庞大的支出&#xff0c;如何及时发现并控制不合理支出&#xff0c;成为企业成本控制的关键。为此&…

引用计数器(kref)

1、什么是引用计数器 如果我们写了一个字符驱动&#xff0c;当硬件设备插上时&#xff0c;系统会生成一个设备节点。用户在应用空间操作这个设备节点就可以操作设备。如果此时将硬件断开&#xff0c;驱动是不是就要立刻释放呢&#xff1f;如果立刻释放&#xff0c;应用程序是不…

计算机网络体系结构解析

OSI参考模型 与 TCP/IP模型 如图所示 TCP/IP模型有几层 应用层&#xff1a;只需要专注于为用户提供应用功能 HTTP、SMTP、Telnet等&#xff0c;工作在操作系统中的用户态&#xff0c;传输层及以下工作在内核态传输层&#xff1a;为应用层提供网络支持&#xff08;TCP、UDP传…