数据结构专题实验7——图的应用(景点管理)(C++实现)

这篇具有很好参考价值的文章主要介绍了数据结构专题实验7——图的应用(景点管理)(C++实现)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、实验概述

实验内容:应用图的技术,根据需求文件要求的功能,实现旅游景点的管理。实验要求:

  1. 使用图的数据结构建立一个景点图的结构。
  2. 可以查找各景点信息。
  3. 旅游景点导航,使用深度优先,从一个景点开始遍历所有景点。
  4. 查找一个景点到另一个景点的最短路径。
  5. 对景点道路进行规划(使用最小生成树,使铺设的景点总道路长最短)。

二、代码结构

数据结构 景点管理,数据结构学期实训,数据结构,c++,qt,图论,软件工程

	旅游景点实际上就是无向图(有向图),这里利用无向图实现,运用了
一些经典的图的算法,例如:深度优先遍历、prim算法、最小生成树。而图也可
以抽象为一个矩阵。
	景点结构体vex,包括景点编号,景点名称,景点简介。
	边结构体edge,代表两个景点之间有道路(邻接矩阵)。

数据结构 景点管理,数据结构学期实训,数据结构,c++,qt,图论,软件工程

三、函数讲解

void Init()

	初始化Graph类,生成一个空的景点图(矩阵)。
void Graph::Init(){
    vexnum = 0;//初始化点的数量
    memset(matrix,0,sizeof(matrix));//初始化当前的图(点、边、权重)
    memset(vexs,0,sizeof(vexs));//初始化当前的点
}

bool InsertVex(Vex vex)

	添加点到vexs数组中。
bool Graph::InsertVex(Vex vex){
    if(vexnum!=SIZE){
    vexs[vexnum].num = vex.num;
    vexs[vexnum].name = vex.name;
    vexs[vexnum++].introduction = vex.introduction;
    }
    else
    return false;
    return true;
}

bool InsertEdge(Edge edge)

	将边edge的信息保存到邻接矩阵matrix中。
bool Graph::InsertEdge(Edge edge){
    for(int i = 0;i < vexnum;i++)
        for(int j = 0;j < vexnum;j++)
            if(i == edge.vex1 && j == edge.vex2){
                matrix[i][j] = edge.weight;
                return true;
            }
    return false;
}

Vex getVet(string name)

	查询点的信息。
Graph::Vex Graph::getVet(string name){
    for(int i = 0;i < vexnum;i++)
        if(name == vexs[i].name)
           return vexs[i];
}

int FindEdge(int nVex,Edge edges[])

	查询与一个点相连的边。
int Graph::FindEdge(int nVex,Edge edges[]){
    int index = 0;
    for(int j = 0;j < vexnum;j++)
        if(matrix[nVex][j]!=0){
            edges[index].vex1 = nVex;
            edges[index].vex2 = j;
            edges[index++].weight = matrix[nVex][j];
        }
    return index;
}

int getVexNum()

	得到当前点的个数。
int Graph::getVexNum(){
    return vexnum;
}

int FindShortPath(int start,int end,string &path)

	找到两点间最短路径。
	第一个嵌套for循环是为了将有向图变为无向图,大家可以根据自己的需要
修改,可以改在初始化时就变为无向图。
	distance数组存放最短道路的长度,path数组存放该道路经过景点的顺序
(道路本身)。
	通过佛洛依德算法来更新亮点间的最短路径,比如:A点到B点本身就有直达
的道路,此时distance数组会记录这个数字,但是A点到C点,C点到B点也有道
路,而且A->C->B这一道路长度小于A->B的道路长度,那么distance数组中A点
到B点的距离就会更新为这个更短的长度。所以在循环结束,每两个点之间的道
路都是最短的,因为每一次循环都在更新。
	sign2代表这条道路已经走完,不会继续循环。保证是在两个景点有通路的
前提下进行最小路径的比较。
int Graph::FindShortPath(int start,int end,string &path2){
    int distance[vexnum][vexnum];
    int tempMatrix[vexnum][vexnum];
    memset(tempMatrix,0,sizeof(tempMatrix));

    for(int i = 0;i < vexnum;i++)
        for(int j = 0;j < vexnum;j++)
            if(matrix[i][j]!=0 && matrix[j][i] == 0){
               tempMatrix[i][j] = matrix[i][j];
               tempMatrix[j][i] = matrix[i][j];
            }
    string path[vexnum][vexnum];
    //初始化路径矩阵
    for(int i = 0;i < vexnum;i++)
        for(int j = 0;j < vexnum;j++){
            distance[i][j] = tempMatrix[i][j];
            path[i][j] += to_string(j);
        }
    int sequence[7];
    memset(sequence,-1,sizeof (sequence));
    int sign2 = 0;
    for(int i = start;i < vexnum;i++)
        for(int j = 0;j < vexnum;j++)
              if(i != j)
                 for(int k = 0;k < vexnum;k++)
                    if(distance[i][j]!=0 && distance[j][k]!=0 && sign2 == 0){//&& sign1 == -1 && sign2 == 0
                        if((distance[i][k] > distance[i][j] + distance[j][k])||distance[i][k] == 0){
                            distance[i][k] = distance[i][j] + distance[j][k];
                            path[i][k] += to_string(j);
                            printf("i:%d j:%d k:%d",i,j,k);
                        }
                        if(k == end)
                            sign2 = -1;
                    }
        path2 = path[start][end] += to_string(start);
        cout << start << "->"  << end << ":" << path[start][end];
        printf(" shortestpath:%d ",distance[start][end]);
        printf(" path:%s ",path2.c_str());
        cout << endl;
        return distance[start][end];
}

void MST(Edge edges[])

	构造最小生成树。
	第一个嵌套for循环是为了将有向图变为无向图,大家可以根据自己的需要
修改,可以改在初始化时就变为无向图。
	INFINITY的值我给的是99999。我使用的是prim算法构造最小生成树,从第
一个景点开始,对其邻接的景点道路权重逐一进行比较,选取最小的那一个,
最近的道路会存到cloest数组中,该道路的权重会存到lowcost数组中。通过
一个嵌套for循环来更新最小权重,也能找到相应的最小道路。
void Graph::MST(Edge tree[]){
    int n = 0,min = INFINITY,tempMatrix[vexnum][vexnum],temp = 0;
    int cloest[vexnum],lowcost[vexnum];//closet为顶点i的最近邻点,lowcost存放(i,cloest[i])的权值
    Edge e[vexnum-1];//从每个点出去的边
    memset(cloest,0,sizeof(cloest));
    memset(lowcost,0,sizeof(lowcost));
    memset(tempMatrix,0,sizeof(tempMatrix));

    for(int i = 0;i < vexnum;i++)
        for(int j = 0;j < vexnum;j++)
            if(matrix[i][j]!=0 && matrix[j][i] == 0){//
               tempMatrix[i][j] = matrix[i][j];
               tempMatrix[j][i] = matrix[i][j];
            }

    for(int i = 0;i < vexnum;i++){
        min = INFINITY;
        for(int j = 0;j < vexnum;j++){
            if(tempMatrix[i][j]!=0){
               temp = min;
               min = (min < tempMatrix[i][j])?min:tempMatrix[i][j];
               if(min != temp)
               cloest[i] = j;
            }
        }
        lowcost[i] = min;
    }

    cout << "MST: ";
    for(int i = 0;i < vexnum;i++){
        //cout << i << "——" << cloest[i] ;
        cout << "i: " << i << "  " << cloest[i] ;
    }

    cout << "  lowcost: ";
    for(int i = 0;i < vexnum;i++){
        //cout << i << "——" << cloest[i] ;
        cout << "i: " << i << "  " << lowcost[i] ;
    }
    for(int i = 0;i < vexnum;i++){
        tree[i].vex1 = i;
        tree[i].vex2 = cloest[i];
        tree[i].weight = lowcost[i];
    }
}

void DFS(int nVex,bool visited[],int sequence[],int &index)

	用深度优先搜索遍历图。
	第一个嵌套for循环是为了将有向图变为无向图,大家可以根据自己的需要
修改,可以改在初始化时就变为无向图。
	第二个嵌套for循环是利用邻接矩阵的特性,若有邻接的点,则满足if判断
条件。visited数组记录这个景点是否被遍历过了,sequence数组记录遍历的
顺序。然后在这个循环里递归调用DFS方法,直到visited数组中全都是true。
代表所有景点都已经遍历过了。
void Graph::DFS(int nVex,bool visited[],int sequence[],int &index){
    int tempMatrix[vexnum][vexnum];
    memset(tempMatrix,0,sizeof(tempMatrix));

    for(int i = 0;i < vexnum;i++)
        for(int j = 0;j < vexnum;j++)
            if(matrix[i][j]!=0 && matrix[j][i] == 0){
               tempMatrix[i][j] = matrix[i][j];
               tempMatrix[j][i] = matrix[i][j];
            }
    for(int i = 0;i < vexnum;i++)
       for(int j = 0;j  < vexnum;j++){
           if(tempMatrix[nVex][j]!=0 && !visited[j]){
              visited[j] = true;
              sequence[index++] = j;
              DFS(j,visited,sequence,index);
              printf("j:%d  ",j);
           }
       }
}

四、结果演示

	点击查看路线按钮,展示整个景点图。

数据结构 景点管理,数据结构学期实训,数据结构,c++,qt,图论,软件工程

	点击推荐游览路线按钮,展示最小生成树。

数据结构 景点管理,数据结构学期实训,数据结构,c++,qt,图论,软件工程

	输入一个景点名,点击景点导航,展示深度优先遍历结果。

数据结构 景点管理,数据结构学期实训,数据结构,c++,qt,图论,软件工程

	输入两个景点名,点击推荐路线,寻找最短路径。

数据结构 景点管理,数据结构学期实训,数据结构,c++,qt,图论,软件工程

	输入一个景点名称,点击景点信息,在下方文字框中展示景点信息。

数据结构 景点管理,数据结构学期实训,数据结构,c++,qt,图论,软件工程
我在github上做的开源。文章来源地址https://www.toymoban.com/news/detail-766692.html

到了这里,关于数据结构专题实验7——图的应用(景点管理)(C++实现)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构(30)】6.6 图的应用

    其中: 拓扑排序 以及 关键路径 针对的是一种特殊的图,称作 有向无环图 。 生成树 图中所有顶点均由边连接在一起,但是 不存在回路 的图。 包含无向图 G 所有顶点的 极小连通子图 。 极小连通子图 : 顶点的边数目在这个连通子图中的数目已经达到最小。 如果在该图中

    2024年02月01日
    浏览(40)
  • 数据结构:地图着色问题——图的应用——回溯法

    目录 前言 一、解决问题的思路 二、存储结构设计 三、代码 1.创建图函数 2.判断色号是否相同函数 3.回溯函数 4.整体代码 总结 本次解决的问题:用图模拟部分地图,对各省进行着色,要求相邻省所使用的颜色不同,并保证使用的颜色总数最少。 先来一张效果图 将邻接矩阵

    2024年02月04日
    浏览(54)
  • 数据结构第三遍补充(图的应用)

    Kruskal算法实现的关键是:当一条边加入到TE的集合后,如何判断是否构成回路? 答: 简单的解决方法是:定义一个一维数组Vset[n]; 存放图T中每个顶点所在的连通分量的编号。 ① 初值: Vset[i]=i, 表示每个顶点各自组成一个连通分量,连通分量的编号简单地使用顶点在图中的位置

    2024年02月06日
    浏览(47)
  • 【开卷数据结构 】图的应用——最短生成树

    目录 最小生成树 Prim算法实现最小生成树 kruskal算法实现最小生成树 Q:什么是广度优先搜索 A: 一个连通图的生成树含有图中全部的顶点,并且只含尽可能少的边 。若砍去它的一条边,则会使生成树变成非连通图。若给它增加一条边,则会形成图中的一条回路。 对于一个带

    2023年04月09日
    浏览(48)
  • 数据结构和算法专题---3、失效算法与应用

    本章我们会对失效算法做个简单介绍,包括常用的失效算法(先来先淘汰(FIFO)、最久未用淘汰(LRU)、最近最少使用(LFU))的概述、实现方式、典型场景做个说明。 失效算法常见于缓存系统中。因为缓存往往占据大量内存,而内存空间是相对昂贵,且空间有限的,那么

    2024年02月04日
    浏览(44)
  • 数据结构-图的遍历和应用(DAG、AOV、AOE网)

    目录 *一、广度优先遍历(BFS) 广度优先生成树 广度优先生成森林 *二、深度优先遍历 深度优先生成树 深度优先生成森林 二、应用 2.1最小生成树 *Prim算法 *Kruskal算法 2.2最短路径  *BFS算法 *Dijkstra算法  *Floyd算法 *2.3有向无环图(DAG网)  *2.4拓扑排序(AOV网) *逆拓扑排序  *2.5关键路

    2024年02月10日
    浏览(41)
  • 数据结构和算法专题---4、限流算法与应用

    本章我们会对限流算法做个简单介绍,包括常用的限流算法(计数器、漏桶算法、令牌桶案发、滑动窗口)的概述、实现方式、典型场景做个说明。 限流是对系统的一种保护措施。即限制流量请求的频率(每秒处理多少个请求)。一般来说,当请求流量超过系统的瓶颈,则丢

    2024年02月04日
    浏览(49)
  • C语言---数据结构实验---哈夫曼树及哈夫曼编码的算法实现---图的基本操作

    本篇实验代码非本人写,代码源自外部,经调试解决了部分warning和error后在本地vs上可以正常运行,如有运行失败可换至vs 未来会重构实现该两个实验 内容要求: 1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并建立哈夫曼树 2、建立编码

    2024年02月13日
    浏览(58)
  • 数据结构实验6 :图的存储与遍历(邻接矩阵的深度优先遍历DFS和邻接表的广度优先遍历BFS)

    利用邻接矩阵存储无向图,并从0号顶点开始进行深度优先遍历。 输入第一行是两个整数n1 n2,其中n1表示顶点数(则顶点编号为0至n1-1),n2表示图中的边数。 之后有n2行输入,每行输入表示一条边,格式是“顶点1 顶点2”,把边插入图中。 例如: 4 4 0 1 1 3 0 3 0 2 先输出存储

    2024年02月09日
    浏览(67)
  • 【数据结构】图的应用:最小生成树;最短路径;有向无环图描述表达式;拓扑排序;逆拓扑排序;关键路径

    目录 1、最小生成树 1.1 概念  1.2 普利姆算法(Prim) 1.3 克鲁斯卡尔算法(Kruskal)  2、最短路径 2.1 迪杰斯特拉算法(Dijkstra) 2.2 弗洛伊德算法(Floyd)  2.3 BFS算法,Dijkstra算法,Floyd算法的对比 3、有向无环图描述表达式 3.1 有向无环图定义及特点 3.2 描述表达式 4、拓扑排序

    2024年02月07日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包