图的操作和应用之景区信息管理系统(数据结构课程设计)

简介: 0001:图的操作和应用之景区信息管理系统(C++版数据结构课程设计)现有一个景区,景区里面有若干个景点,景点之间满足以下条件:(1) 某些景点之间铺设了道路(相邻)(2) 这些道路都是可以双向行驶的(无向图)(3) 从任意一个景点出发都可以游览整个景区(连通图)开发景区信息管理系统,对景区的信息进行管理。使用图的数据结构来保存景区景点信息,为用户提供创建图、查询景点信息、旅游景点导航、搜索最短路径、铺设电路规划等功能。文章目录0001:图的操作和应用之景区信息管理系统(C++版数据结构课程设

0001:图的操作和应用之景区信息管理系统(C++版数据结构课程设计)

现有一个景区,景区里面有若干个景点,景点之间满足以下条件:

(1) 某些景点之间铺设了道路(相邻)

(2) 这些道路都是可以双向行驶的(无向图)

(3) 从任意一个景点出发都可以游览整个景区(连通图)

开发景区信息管理系统,对景区的信息进行管理。使用图的数据结构来保存景区景点信息,为用户提供创建图、查询景点信息、旅游景点导航、搜索最短路径、铺设电路规划等功能。


@TOC


前言

数据结构是计算机学科实践性很强的一门核心课程。课程设计是加强学生实践能力的一个强有力手段,要求学生掌握数据结构的应用、算法的编写、类C语言的算法转换成C/C++/Java程序并上机调试的基本方法,还要求学生在完成程序设计的同时能够写出比较规范的设计报告。严格实施课程设计这一环节,对于学生基本程序设计素养的培养和软件工作者工作作风的训练,将起到显著的促进作用。


一、设计要求

1.景区信息路线图

景区路线图

景区信息

2.设计要求

(1) 读文件创建图

输入:从Vex.txt文件中读取景点信息,从Edge.txt文件中读取道路信息。

处理:根据读取的景区信息创建景区景点图。

(2) 查询景点

输入:想要查询的景点的编号。

处理:根据输入的景点编号,查询该景点及相邻景点的信息。

输出:

① 景点名字

② 景点介绍

③ 相邻景区的名字

④ 到达相邻景区的路径长度

(3) 旅游景点导航

输入:起始景点的编号。

处理:使用深度优先搜索(DFS)算法,查询以该景点为起点,无回路游览整个景区的路线。

输出:所有符合要求的导航路线。

(4) 搜索最短路径

输入:

① 起始景点的编号

② 终点的编号。

处理:使用迪杰斯特拉(Dijkstra)算法,求得从起始景点到终点之间的最短路径,计算路径总长度。

输出:

① 最短路线

② 路径总长度

(5) 铺设电路规划

处理:根据景区景点图使用普里姆(Prim)算法构造最小生成树,设计出一套铺设线路最短,但能满足每个景点都能通电的方案。

输出:

① 需要铺设电路的道路

② 每条道路铺设电路的长度

③ 铺设电路的总长度

(6) 修改图保存文件

插入、删除、修改顶点、边的信息,注意顶点和边的关系,之后保存文件,重新读取文件建立图的存储结构并显示。

重点注意顶点和边的关系,考虑边是否重复?顶点是否存在?……

二、关键代码

1.类的设计

点的类 Node.h:

#ifndef NODE_H_INCLUDED
#define NODE_H_INCLUDED
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
class Node
{
public:
    bool visited;
    Node(int number=-1,string name=" ",string introduction=" ");
    int m_number;
    string m_name;
    string m_introduction;
    //void SeekNode(int number);
};
#endif // NODE_H_INCLUDED

边的类 Edge.h:

#ifndef EDGE_H_INCLUDED
#define EDGE_H_INCLUDED
#include <iostream>
class Edge
{
public:
    Edge(int nodeIndexA=0,int nodeIndexB=0,int weightValue=0);
    int m_iNodeIndexA;
    int m_iNodeIndexB;
    int m_iWeightValue;
    bool m_bSelected;
};
#endif // EDGE_H_INCLUDED

图的类 Map.h:

#ifndef MAP_H_INCLUDED
#define MAP_H_INCLUDED
#include <vector>
#include "Node.h"
#include "Edge.h"
using namespace std;
class Map
{
public:
    Map(int capacity);
    ~Map();
    bool addNode(Node *pNode);// 向图中添加顶点
    void resetNode();//重置顶点
    bool setValueToMatrixForUndirectedGraph(int row,int cli,int val=1);//设置邻接矩阵
    void printMatrix();//打印邻接矩阵
    void DFS(int nodeIndex,int beginNum);//深度优先遍历
    void seekNode(int number);//查询景点
    void mapDFS(int nodeIndex);//旅游景点导航
    void primTree(int nodeIndex);//普利姆算法生成树
    void Dijkstra(int v0,int v1);//迪杰斯特拉算法
    bool hasNode(string nodeName);
    bool hasEdge(int NodeAnum,int NodeBnum);
private:
    bool getValueFromMatricx(int row,int col,int &val);//从矩阵中获取权值
    void breadthFirstTraverseImpl(vector <int> preVec);//广度优先遍历实现函数
    int getMinEdge(vector<Edge> edgeVec);
private:
    int m_iCapacity;//最多可以容纳的顶点数
    int m_iNodeCount; //已经添加的顶点个数
    Node *m_pNodeArray;//用来存放顶点数组
    int *m_pMatrix; //用来存放邻接矩阵
    Edge *m_pEdge;//用来存放边数组
};
#endif // MAP_H_INCLUDED

2.重要算法

迪杰斯特拉(Dijkstra)算法函数:

void Map::Dijkstra(int v0,int v1)
{
    int dist[m_iCapacity];
    int path[m_iCapacity];
    bool final[m_iCapacity];
    dist[v0]=0;
    path[v0]=v0;
    for(int i=1;i<m_iCapacity;i++)
    {
      if(m_pMatrix[v0*m_iCapacity+i]!=0)
      {
      dist[i]=m_pMatrix[v0*m_iCapacity+i];
      }
      else
      {
      dist[i]=100000;
      }
      path[i]=v0;
      final[i]=false;
    }
    for(int i=0;i<m_iCapacity;i++)
        {
        int minds=100000;
        int ind=10000;
        for(int j=0;j<m_iCapacity;j++){//寻找目前的路径距离中最小的一个
            if(!final[j]&&dist[j]<minds){
                minds=dist[j];
                ind=j;
            }
        }
        final[ind]=true;
        for(int j=0;j<m_iCapacity;j++)
         {//更新dist
           if(m_pMatrix[ind*m_iCapacity+j]!=0&&!final[j]&&(minds+m_pMatrix[ind*m_iCapacity+j])<dist[j])
            {
              dist[j]=minds+m_pMatrix[ind*m_iCapacity+j];
              path[j]=ind;
            }
         }
       }
    //路线规划 倒置的
    int endNum=v1;
    vector <int> ewayNum;
   while(1)
    {
      if(path[endNum]!=v0)
        {
         ewayNum.push_back(endNum);
         endNum=path[endNum];
        }
      if(path[endNum]==v0)
      {
          ewayNum.push_back(endNum);
          break;
      }
    }
   //转换成正置路线
    int wayNum[ewayNum.capacity()];
    for(int i=0;i<(int)ewayNum.capacity();i++)
    {
        wayNum[i]=ewayNum[ewayNum.capacity()-1-i];
    }
    //输出正置路线
    cout<<v0<<endl;
    for(int i=0;i<(int)ewayNum.capacity();i++)
    {
        cout<<wayNum[i]<<endl;
    }
    cout<<dist[v1]<<endl;
}

普利姆(Prim)算法函数:

void Map::primTree(int nodeIndex)
{
    int AllWeightValue=0;
    int value=0;
    int edgeCount=0;
    vector <int> nodeVec;
    vector <Edge> edgeVec;
    //cout<<m_pNodeArray[nodeIndex].m_name<<endl;
    nodeVec.push_back(nodeIndex);
    m_pNodeArray[nodeIndex].visited=true;
    while(edgeCount<m_iCapacity-1)
    {
        int temp=nodeVec.back();
        for(int i=0;i<m_iCapacity;i++)
        {
            getValueFromMatricx(temp,i,value);
            if(value!=0)
            {
                if(m_pNodeArray[i].visited)
                {
                    continue;
                }
                else
                {
                    Edge edge(temp,i,value);
                    edgeVec.push_back(edge);
                }
            }
        }
     //从可选边集合中选出最小边
      int edgeIndex=getMinEdge(edgeVec);
      edgeVec[edgeIndex].m_bSelected=true;
      cout<<edgeVec[edgeIndex].m_iNodeIndexA<<"---"<<edgeVec[edgeIndex].m_iNodeIndexB<<" ";
      cout<<edgeVec[edgeIndex].m_iWeightValue<<endl;
      AllWeightValue+=edgeVec[edgeIndex].m_iWeightValue;
      m_pEdge[edgeCount]=edgeVec[edgeIndex];
      edgeCount++;
      int nextNodeIndex=edgeVec[edgeIndex].m_iNodeIndexB;
      nodeVec.push_back(nextNodeIndex);
      m_pNodeArray[nextNodeIndex].visited=true;
     // cout<<m_pNodeArray[nextNodeIndex].m_introduction<<endl;
    }
    cout<<AllWeightValue<<endl;
    for(int j=0;j<m_iCapacity-1;j++)
    {
        m_pNodeArray[j].visited=false;
    }
}

三、运行截图

1.主界面

在这里插入图片描述

2.输出邻接矩阵

在这里插入图片描述

3.查询景点

在这里插入图片描述

4.旅游景点导航(路径搜索)

在这里插入图片描述

5.搜索最短路径(迪杰斯特拉算法)

在这里插入图片描述

6.铺设电路规划(普利姆算法求最小生成树)

在这里插入图片描述

7.动态操作(对景点或者边增删改)


如需要本资源下载也可以直接添加作者QQ,并可以获取资源预览、软件安装、工程导入、协助运行、算法解释、报告协助撰写等售后服务

随时在线,欢迎交流

QQ:2215991436(心源易码 派大星)

备用QQ:402501817(心源易码 佩奇)

相关文章
|
3月前
|
存储 Java
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
56 1
|
3月前
|
存储 算法 C语言
通义灵码在考研C语言和数据结构中的应用实践 1-5
通义灵码在考研C语言和数据结构中的应用实践,体验通义灵码的强大思路。《趣学C语言和数据结构100例》精选了五个经典问题及其解决方案,包括求最大公约数和最小公倍数、统计字符类型、求特殊数列和、计算阶乘和双阶乘、以及求斐波那契数列的前20项和。通过这些实例,帮助读者掌握C语言的基本语法和常用算法,提升编程能力。
97 4
|
3月前
|
机器学习/深度学习 存储 人工智能
数据结构在实际开发中的广泛应用
【10月更文挑战第20天】数据结构是软件开发的基础,它们贯穿于各种应用场景中,为解决实际问题提供了有力的支持。不同的数据结构具有不同的特点和优势,开发者需要根据具体需求选择合适的数据结构,以实现高效、可靠的程序设计。
234 63
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
78 5
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
71 1
|
2月前
|
缓存 NoSQL PHP
Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出
本文深入探讨了Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出。文章还介绍了Redis在页面缓存、数据缓存和会话缓存等应用场景中的使用,并强调了缓存数据一致性、过期时间设置、容量控制和安全问题的重要性。
47 5
|
3月前
探索数据结构:队列的的实现与应用
探索数据结构:队列的的实现与应用
|
3月前
|
存储
探索数据结构:单链表的实践和应用
探索数据结构:单链表的实践和应用
|
3月前
|
存储 测试技术
探索数据结构:顺序表的实现与应用
探索数据结构:顺序表的实现与应用