C++ 数据结构图(1)

1. 图的基本概念

        

                图是由顶点集合及顶点间的关系组成的一种数据结构:G = (V, E) ,其中:
 顶点集合 V = {x|x 属于某个数据对象集 } 是有穷非空集合 E = {(x,y)|x,y 属于 V} 或者 E = {<x, y>|x,y 属于 V && Path(x, y)} 是顶点间关系的有穷集合,也叫 做边的集合 。 (x, y)表示 x y 的一条双向通路,即 (x, y) 是无方向的; Path(x, y) 表示从 x y 的一条单向通路,即 Path(x, y)是有方向的。顶点和边:图中结点称为顶点 ,第 i 个顶点记作 vi 两个顶点 vi vj 相关联称作顶点 vi 和顶点 vj 之间 有一条边 ,图中的第 k 条边记作 ek ek = (vi vj) <vi vj> 。有向图和无向图:在有向图中,顶点对 <x, y> 是有序的,顶点对 <x y> 称为顶点 x 到顶点 y 的一条 ( ) <x, y> <y, x> 是两条不同的边 ,比如下图 G3 G4 为有向图。在 无向图中,顶点对 (x, y) 是无序的,顶点对 (x,y) 称为顶点 x 和顶点 y 相关联的一条边,这条边没有特定方向, (x, y) (y x) 是同一条边 ,比如下图 G1 G2 为无向图。注意: 无向边 (x, y) 等于有向边 <x, y> <y, x>

完全图:在 n 个顶点的无向图中 ,若 n * (n-1)/2 条边 ,即 任意两个顶点之间有且仅有一条边
则称此图为 无向完全图 ,比如上图 G1 ;在 n 个顶点的有向图 中,若 n * (n-1) 条边 ,即 任意两个
顶点之间有且仅有方向相反的边 ,则称此图为 有向完全图 ,比如上图 G4
邻接顶点:在 无向图中 G 中,若 (u, v) E(G) 中的一条边,则称 u v 互为邻接顶点 ,并称 (u,v)
附于顶点 u v ;在 有向图 G 中,若 <u, v> E(G) 中的一条边,则称顶点 u 邻接到 v ,顶点 v 邻接自顶
u ,并称边 <u, v> 与顶点 u 和顶点 v 相关联
顶点的度: 顶点 v 的度是指与它相关联的边的条数,记作 deg(v) 。在有向图中, 顶点的度等于该顶
点的入度与出度之和 ,其中顶点 v 入度是以 v 为终点的有向边的条数 ,记作 indev(v); 顶点 v 出度
是以 v 为起始点的有向边的条数 ,记作 outdev(v) 。因此: dev(v) = indev(v) + outdev(v) 。注
意:对于 无向图,顶点的度等于该顶点的入度和出度 ,即 dev(v) = indev(v) = outdev(v) 。路径:在图G = (V E) 中,若 从顶点 vi 出发有一组边使其可到达顶点 vj ,则称顶点 vi 到顶点 vj 的顶 点序列为从顶点 vi 到顶点 vj 的路径 。路径长度:对于不带权的图,一条路径的路径长度是指该路径上的边的条数 ;对于 带权的图,一 条路 径的路径长度是指该路径上各个边权值的总和

简单路径与回路: 若路径上各顶点 v1 v2 v3 vm 均不重复,则称这样的路径为简单路
若路 径上第一个顶点 v1 和最后一个顶点 vm 重合,则称这样的路径为回路或环

子图: 设图 G = {V, E} 和图 G1 = {V1 E1} ,若 V1 属于 V E1 属于 E ,则称 G1 G 的子图

连通图:在 无向图 中,若从顶点 v1 到顶点 v2 有路径,则称顶点 v1 与顶点 v2 是连通的。 如果图中任
意一 对顶点都是连通的,则称此图为连通图
强连通图:在 有向图 中,若在 每一对顶点 vi vj 之间都存在一条从 vi vj 的路径,也存在一条从 vj
vi 的路径,则称此图是强连通图
生成树:一个 连通图的最小连通子图 称作该图的生成树。 n 个顶点的连通图的生成树有 n 个顶点
n- 1 条边。

2. 图的存储结构

因为图中既有节点,又有边 ( 节点与节点之间的关系 ) ,因此, 在图的存储中,只需要保存:节点和
边关系即可 。节点保存比较简单,只需要一段连续空间即可,那边关系该怎么保存呢?

2.1 邻接矩阵

因为节点与节点之间的关系就是连通与否,即为 0 或者 1 ,因此 邻接矩阵 ( 二维数组 ) 即是:先用一
个数组将定点保存,然后采用矩阵来表示节点与节点之间的关系

注意:
1. 无向图的邻接矩阵是对称的 i ( ) 元素之和,就是顶点 i 的度 有向图的邻接矩阵则不一 定是对称的,第 i ( ) 元素之后就是顶点 i 的出 ( )
2. 如果边带有权值,并且两个节点之间是连通的,上图中的边的关系就用权值代替,如果两个顶点不通,则使用无穷大代替。

3. 用邻接矩阵存储图的有点是能够快速知道两个顶点是否连通,缺陷是如果顶点比较多,边比较少时,矩阵中存储了大量的0 成为系数矩阵,比较浪费空间,并且要求两个节点之间的路径不是很好求。

#include <iostream>
#include <vector>
#include <map>
#include <climits>
#include <algorithm>
using namespace std;template <class V, class W, W MAX_W = INT_MAX, bool Direction = false>class Graph
{public:typedef Graph<V, W, MAX_W, Direction> Self;Graph() = default;Graph(const V *vertexs, size_t n){// reverse 只是预留了,没有做填充。resize() 是做了填充的,默认是用0 做了填充,_vertexs.reserve(n);for (size_t i = 0; i < n; i++){_vertexs.push_back(vertexs[i]);_vIndexMap[_vertexs[i]] = i;}//将MAX_W 作为一个边部存在 的标示值_matrix.resize(n);for (auto &e : _matrix){e.resize(n, MAX_W);}}//输入顶点获取顶点的边的数量size_t GetVertexIndex(const V &v){auto ret = _vIndexMap.find(v);if (ret != _vIndexMap.end()){return ret->second;}else{throw invalid_argument("不存在顶点");return -1;}}void _AddEdge(size_t srci, size_t dsti, const W &w){_matrix[srci][dsti] = w;if (Direction == false){_matrix[dsti][srci] = w;}}void AddEdge(const V &src, const V &dst, const W &w){size_t srci = GetVertexIndex(src);size_t dsti = GetVertexIndex(dst);_AddEdge(srci, dsti, w);}void Print(){// 打印顶点和下标映射关系for (size_t i = 0; i < _vertexs.size(); ++i){cout << _vertexs[i] << "-" << i << " ";}cout << endl<< endl;cout << " ";for (size_t i = 0; i < _vertexs.size(); ++i){cout << i << " ";}cout << endl;// 打印矩阵for (size_t i = 0; i < _matrix.size(); ++i){cout << i << " ";for (size_t j = 0; j < _matrix[i].size(); ++j){if (_matrix[i][j] != MAX_W)cout << _matrix[i][j] << " ";elsecout << "#"<< " ";}cout << endl;}cout << endl<< endl;// 打印所有的边for (size_t i = 0; i < _matrix.size(); ++i){for (size_t j = 0; j < _matrix[i].size(); ++j){if (i < j && _matrix[i][j] != MAX_W){cout << _vertexs[i] << "-" << _vertexs[j] << ":" << _matrix[i][j] << endl;}}}}private://存储键值的顶点map<V, size_t> _vIndexMap;vector<V> _vertexs;        //顶点集合vector<vector<W>> _matrix; //存储边集合的矩阵
};int main()
{Graph<char, int, INT_MAX, true> g("01234", 4);g.AddEdge('0', '1', 1);g.AddEdge('0', '3', 4);g.AddEdge('1', '3', 2);g.AddEdge('1', '2', 9);g.AddEdge('2', '3', 8);g.AddEdge('2', '1', 5);g.AddEdge('2', '0', 3);g.AddEdge('3', '2', 6);g.Print();system("pause");return 0;
}

 

2.2 邻接表

邻接表:使用数组表示顶点的集合,使用链表表示边的关系

1. 无向图邻接表存储

注意: 无向图中同一条边在邻接表中出现了两次。如果想知道顶点 vi 的度,只需要知道顶点 vi 边链表集合中结点的数目即可
2. 有向图邻接表存储

注意:有向图中每条边在邻接表中只出现一次,与顶点 vi 对应的邻接表所含结点的个数,就是该顶点的出度,也称出度表,要得到vi 顶点的入度,必须检测其他所有顶点对应的边链表,看有多少边顶点的dst 取值是 i
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;namespace LinkTable
{template <class W>struct LinkEgde{int _srcIndex;int _dstIndex;W _w;LinkEgde<W> *_next;LinkEgde(const W &w) : _srcIndex(-1), _dstIndex(-1), _w(w), _next(nullptr) {}};template <class V, class W, bool Direction = false>class Graph{typedef LinkEgde<W> Edge;public:Graph(const V *vertexs, size_t n){_vertexs.reserve(n);for (size_t i = 0; i < n; i++){_vertexs.push_back(_vertexs[i]);_vIndexMap[_vertexs[i]] = i;}_linkTable.resize(n, nullptr);}size_t GetVertexIndex(const V &v){auto ret = _vIndexMap.find(v);if (ret != _vIndexMap.end()){return ret->second;}else{throw invalid_argument("not exist vertex");return -1;}}void AddEdge(const V &src, const V &dst, const W &w){size_t srcindex = GetVertexIndex(src);size_t dstindex = GetVertexIndex(dst);Edge *sd_edge = new Edge(w);sd_edge->_srcIndex = srcindex;sd_edge->_dstIndex = dstindex;sd_edge->_next = _linkTable[srcindex];_linkTable[srcindex] = sd_edge;//如果是无向图if (Direction == false){Edge *ds_edge = new Edge(w);ds_edge->_srcIndex = dstindex;ds_edge->_dstIndex = srcindex;ds_edge->_next = _linkTable[dstindex];_linkTable[dstindex] = ds_edge;}}private:map<string, int> _vIndexMap;vector<V> _vertexs;        //顶点集合vector<Edge *> _linkTable; //边的集合};void TestGraph(){string a[] = {"zhangsan", "lisi", "wangwu", "zhaoliu"};Graph<string, int> g1(a, 4);g1.AddEdge("zhangsan", "lisi", 100);g1.AddEdge("zhangsan", "wangwu", 200);g1.AddEdge("wangwu", "zhaoliu", 30);}}int main()
{LinkTable::TestGraph();system("pause");return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

那些无法避免的弯路

近日&#xff0c;某高校毕业生在校期间窃取学校内网数据&#xff0c;收集全校学生个人隐私信息的新闻引发了人们对互联网生活中个人信息安全问题的再度关注。在大数据时代&#xff0c;算法分发带来了隐私侵犯&#xff0c;在享受消费生活等便捷权利的同时&#xff0c;似乎又有不…

Lion:闭源大语言模型的对抗蒸馏

Lion&#xff1a;闭源大语言模型的对抗蒸馏 Lion&#xff0c;由香港科技大学提出的针对闭源大语言模型的对抗蒸馏框架&#xff0c;成功将 ChatGPT 的知识转移到了参数量 7B的 LLaMA 模型&#xff08;命名为 Lion&#xff09;&#xff0c;在只有 70k训练数据的情况下&#xff0…

84、基于stm32单片机超市自助存储柜快递箱系统设计(程序+原理图+流程图+参考论文+开题报告+任务书+设计资料+元器件清单等)

单片机主芯片选择方案 方案一&#xff1a;AT89C51是美国ATMEL公司生产的低电压&#xff0c;高性能CMOS型8位单片机&#xff0c;器件采用ATMEL公司的高密度、非易失性存储技术生产&#xff0c;兼容标准MCS-51指令系统&#xff0c;片内置通用8位中央处理器(CPU)和Flash存储单元&a…

select 框添加树结构(todu)

1. 案例: 2. 代码 下班了&#xff0c;明天写

短视频seo矩阵+抖音小程序源码开发解决方案(一)

该解决方案主要针对产品用户交易决策周期长/非标定制等情况的企业&#xff0c;如&#xff1a;房产、汽车、金融、咨询服务&#xff0c;广告设计、网络科技公司&#xff0c;TOB类销售行业等。 基于不同的经营场景&#xff0c;解决方案全面更新&#xff0c;新增账号管理&#xf…

【嵌入式Qt开发入门】如何使用Qt进行文本读写——QFile读写文本

在很多时候我们需要读写文本文件进行读写&#xff0c;比如写个 Mp3 音乐播放器需要读 Mp3 歌词里的文本&#xff0c;比如修改了一个 txt 文件后保存&#xff0c;就需要对这个文件进行读写操作。本文介绍简单的文本文件读写&#xff0c;内容精简&#xff0c;让大家了解文本读写的…

JavaWeb 速通HTML(常用标签汇总及演示)

目录 一、拾枝杂谈 1.网页组成 : 1 结构 2 表现 3 行为 2.HTML入门 : 1 基本介绍 2.基本结构 : 3.HTML标签 : 1 基本说明 2 注意事项 二、常用标签汇总及演示 1.font标签 : 1 定义 2 演示 2.字符实体 : 1 定义 2 演示 3.标题标签 : 1 定义 2 演示 4. 超链接标签 : 1…

2023年07月在线IDE流行度最新排名

点击查看最新在线IDE流行度最新排名&#xff08;每月更新&#xff09; 2023年07月在线IDE流行度最新排名 TOP 在线IDE排名是通过分析在线ide名称在谷歌上被搜索的频率而创建的 在线IDE被搜索的次数越多&#xff0c;人们就会认为它越受欢迎。原始数据来自谷歌Trends 如果您相…

【CSS】定位

&#x1f4dd;个人主页&#xff1a;爱吃炫迈 &#x1f48c;系列专栏&#xff1a;HTMLCSS &#x1f9d1;‍&#x1f4bb;座右铭&#xff1a;道阻且长&#xff0c;行则将至&#x1f497; 文章目录 标准流&#xff08;Normal Flow&#xff09;元素定位position属性静态定位-static…

Squid代理服务器应用

目录 一、概述 1.代理的工作机制 2.代理服务器的概念 3.作用 4.Squid代理类型 二、安装 Squid 服务 1.编译安装 Squid 2.修改 Squid 的配置文件 3. Squid 的运行控制 4.Squid 服务自动化管理 4.1编写 squid 服务脚本 4.2加入系统服务 三、构建传统代理服务器 1.修…

迈瑞BC系列出图汇总

迈瑞的几个仪器出图需要画图&#xff0c;搞的很费劲&#xff0c;没办法&#xff0c;厂商自己不改&#xff0c;明明有图发Base64串的&#xff0c;就非两个图要自己画&#xff0c;画的方法又描述不清。每个LIS厂商都要浪费很多时间&#xff0c;没什么必要浪费在这种没意义的事情上…

对于大连企业而言如何提升网站的曝光率

对于大连企业而言&#xff0c;提升网站的曝光率是非常重要的&#xff0c;可以通过以下几种方式来实现&#xff1a; 1. 优化网站结构和内容&#xff1a;确保网站的结构清晰&#xff0c;布局合理&#xff0c;并且内容丰富、有吸引力。网站的页面加载速度也要快&#xff0c;以提升…