【图】图的相关概念以及图的存储
来源:互联网 发布:淘宝超级运动会是什么 编辑:程序博客网 时间:2024/06/05 13:56
图的定义
图是一种复杂的非线性结构。
在图形结构中,节点之间的关系是任意的,图中任意两个数据元素之间都有可能相关。
图G由两个集合V(顶点Vertex)和E(边Edge)组成,定义为G=(V,E)。
图的相关概念
1、无向图
无向边:若顶点Vi到Vj之间的边没有方向,则称这条边为无向边,用无序偶对(Vi,Vj)来表示。
如果图中任意两个顶点时间的边都是无向边,则称该图为无向图,
G=(V, {E})、0≤边≤n(n-1)/2。
上图表示:
G=(V,{E}) 其中顶点集合V={A,B,C,D};边集合E={(A,B),(B,C),(C,D),(D,A),(A,C)}
有向图
有向边:若从顶点Vi到Vj的边有方向,则称这条边为有向边,也称为弧。
用有序偶 < Vi,Vj > 来表示,Vi称为弧尾,Vj称为弧头。
如果图中任意两个顶点之间的边都是有向边,则称该图为有向图:
G=(V, {A})、0≤弧≤n(n-1)。
上图表示:
连接顶点A到D的有向边就是弧,A是弧尾,D是弧头,< A, D>表示弧。注意不能写成< D, A>。
对于如上有向图来说,G=(V,{E})其中顶点集合V={A,B,C,D};弧集合E={< A,D >, < B, A>,< C,A >,< B,C >}
3、完全图
完全无向图:若有n个顶点的无向图有n(n-1)/2 条边, 则此图为完全无向图。即,所有的边都是无向边。
完全有向图:有n个顶点的有向图有n(n-1)条边, 则此图为完全有向图。即,所有的边都是有向边。
4、邻接顶点
邻接顶点:在无向图中G中,若(u, v)是E(G)中的一条边,则称u和v互为邻接顶点,并称边(u, v)依附于顶点u和v;在有向图G中,若< u, v>是E(G)中的一条边,则称顶点u邻接到v,顶点v邻接自顶点u,并称边< u, v>与顶点u和顶点v相关联。
5、顶点的度
顶点的度:顶点v的度是指与它相关联的边的条数,记作deg(v)。
在有向图中,顶点的度等于该顶点的入度与出度之和,其中顶点v的入度是以v为终点的有向边的条数,记作indev(v);顶点v的出度是以v为起始点的有向边的条数,记作outdev(v)。因此:
dev(v) = indev(v) + outdev(v)
对于无向图,顶点的度等于该顶点的入度和出度,即dev(v) = indev(v) = outdev(v)。
记住,不管是无向图还是有向图,顶点数n,边数e和顶点的度数有如下关系:
因此,就拿有向图(b)来举例,由公式可以得到图G的边数e=(D(V1)+D(V2)+D(V3)+D(V4))/2=(3+2+2+1)/2=4
6、路径长度
路径长度:对于不带权的图,一条路径的路径长度是指该路径上的边的条数;对于带权的图,一条路径的路径长度是指该路径上各个边权值的总和。
7、连通图(无向图)
在无向图G中,如果图中任意两个顶点vi, vj属于V,vi和vj都是连通的,则图G是连通图。
连通分量:无向图中的极大连通子图
*8、强连通图(有向图)
在有向图G中,如果每一对顶点vi, vj属于V且vi不等于vj,从vi到vj与从vj到vi都存在路径,则图G是连通图。
强连通分量:有向图的极大强连通子图。
9、生成树
生成树:一个连通图的最小连通子图称作该图的生成树。有n个顶点的连通图的生成树有n个顶点和n-1条边。
如果在生成树上添加一条边,必定构成一个环:因为这条边使得它依附的那两个顶点之间有了第二条路径。
一个有n个顶点的生成树有且仅有n-1条边。如果一个图有n个顶点和小于n-1条的边,则是非连通图。如果多余n-1条边,则一定有环。但有n-1条边的图不一定是生成树。
图的存储
(1)邻接矩阵
其实就是用两个数组来表示图。
一维数组存储图中数据元素(顶点)的信息,
二维数组(邻接矩阵)存储图中数据元素之间的关系(边或弧)的信息。
无向图
从上面可以看出,无向图的边数组是一个对称矩阵。
从这个矩阵中,很容易知道图中的信息。
(1)要判断任意两顶点是否有边无边就很容易了;
(2)要计算某个顶点的度,其实就是这个顶点vi在邻接矩阵中第i行或(第i列)的元素之和;
(3)求顶点vi的所有邻接点就是将矩阵中第i行元素扫描一遍,arc[i][j]=1的vj就是邻接点;
而有向图有入度和出度之分:
顶点vi的入度为是第i列各数之和,顶点vi的出度是第i行的各数之和。
有向图
若图G是网图,有n个顶点,则邻接矩阵是一个n*n的方阵,定义为:
可以看出:
(1)第i行权重大于0、小于无穷的个数之和为顶点vi的出度(OD(vi));
(2)第j列权重大于0、小于无穷的个数之和为顶点vj的入度(ID(vj));
(3)第i行和第i列权重大于0、小于无穷的个数之和即为顶点vi的度(TD(vi) = OD(vi) + ID(vj))。
领结矩阵缺点
邻接矩阵形式存储图结构,当e远远小于n^2时,大量的元素是0,造成空间浪费。
邻接矩阵 代码实现:
该类中有三个成员,
一维数组 vector< v> _ver;//存放结点 比如 char A B;
二维数组 vector< vector > _edge;//存放边的权值
bool变量 bool _IsDirected; //true 为有向图
//V表示顶点的类型,比如字符char,数字int//W表示权值,比如int template<class V, class W>class GraphMatrix{public: //默认为无向图,构造函数必须给出顶点的数组及其大小 GraphMatrix(const V* pVer, size_t size, bool isDirected = false) :_IsDirected(isDirected) { //构建两个数组 _ver.resize(size); _edge.resize(size); for (size_t i = 0; i < size; ++i) { _ver[i] = pVer[i];//构建一维数组顶点值 _edge[i].resize(size);//构建二维数组 } } //返回节点的下标 int GetIndexOfVertex(const V& v) { for (size_t i = 0; i < _ver.size(); ++i) { if (_ver[i] == v) return i; } assert(false); return -1; } //添加边,生成图 //对应无向图,需要在二维数组中添加两次,对称 void AddEdge(const V& v1, const V& v2, const W& weight) { int row = GetIndexOfVertex(v1); int col = GetIndexOfVertex(v2); if (_IsDirected)//有向图 { _edge[row][col] = weight; } else//无向图 { _edge[row][col] = weight; _edge[col][row] = weight; } } void Print() { for (size_t i = 0; i < _edge.size(); ++i) { for (size_t j = 0; j < _edge[i].size(); ++j) { cout << _edge[i][j] << " "; } cout << endl; } cout << endl; }private: vector<V> _ver;//存放结点 比如 char A B; vector<vector<W> > _edge;//存放边的权值 bool _IsDirected; //true 为有向图};
(2) 邻接表
邻接表:使用数组表示顶点的集合,使用链表表示边的关系。
无向图
从图中可以看出:同一条边在邻接表中出现了两次。
如果想知道顶点vi的度,只需要知道顶点vi边链表集合中结点的数目即可。
有向图
有向图的邻接表中每条边在邻接表中只出现一次。
出度:与顶点vi对应的邻接表所含结点的个数,就是该顶点的出度,因此也称出度表。
入度:顶点vi的入度,必须检测其他所有顶点对应的边链表,看有多少边顶点的dest与中是i。
邻接表代码实现
实现邻接表,必须有单链表,先给出单链表的节点设计,
四个成员,权值,源节点,目的节点,next指针域。
template<class W>struct LinkEdge{ W _edge;//权值 size_t _srcIndex;//源节点 size_t _desIndex; //目的节点 struct LinkEdge<W>* _pNext;//next指针域 LinkEdge(size_t srcIdx, size_t desIdx, const W& weight) : _edge(weight) , _srcIndex(srcIdx) , _desIndex(desIdx) , _pNext(NULL) {}};
插入一条记录,采用头插的方法,
template<class V, class W>class GraphLink{public: GraphLink() {} GraphLink(const V* pVex, size_t size, bool isDirected) { _vex.resize(size); _LinkTable.resize(size, NULL); for (size_t i = 0; i < size; ++i) _vex[i] = pVex[i]; } //头插法 void _AddEdge(int srcIdx, int desIdx,const W& weight)//为了防止代码重复 { LinkEdge<W>* pEdge = new LinkEdge<W>(srcIdx, desIdx, weight); pEdge->_pNext = _LinkTable[srcIdx]; _LinkTable[srcIdx] = pEdge; } //有向图插入权值,只插入一次,无向图插入两次 void AddEdge(const V& v1, const V& v2, const W& weight) { int srcIdx = GetIndexOfVertex(v1); int desIdx = GetIndexOfVertex(v2); assert(srcIdx != desIdx); //判断是否为有向图:有向图插入权值,只插入一次 _AddEdge(srcIdx, desIdx, weight); if (!_IsDirected) _AddEdge(desIdx, srcIdx, weight); } //获取某个节点的度数:有向图出度和入度 int GetDev(const V& v) { //先求出度(有向图和无向图 都要求) int VertexIdx = GetIndexOfVertex(v); //遍历链表 int OutCount= 0; LinkEdge<W> *pEdge = _LinkTable[VertexIdx]; while (pEdge) { ++OutCount; pEdge = pEdge->_pNext; } //求入度 int InCount= 0; if (_IsDirected) { for (size_t i = 0; i < _LinkTable.size(); ++i) { LinkEdge<W> *pEdge = _LinkTable[i]; if (i != VertexIdx) { while (pEdge) { if (pEdge->_desIndex == VertexIdx) ++InCount; } } } } return InCount + OutCount; } void Print() { cout << " 图的构成:" << endl; for (size_t i = 0; i < _LinkTable.size(); ++i) { LinkEdge<W>* pCur = _LinkTable[i]; cout << i; while (pCur) { cout << " -->" << pCur->_desIndex << "[" << pCur->_edge << "]"; pCur = pCur->_pNext; } cout << " -->NULL" << endl; } cout << endl; }private: //获取顶点的下标 size_t GetIndexOfVertex(const V& v) { for (size_t i = 0; i < _vex.size(); ++i) { if (_vex[i] == v) return i; } assert(false); return -1; }private: vector<V> _vex; vector<LinkEdge<W>*> _LinkTable; bool _IsDirected;};
- 【图】图的相关概念以及图的存储
- 图的相关概念与存储方式
- 图的相关概念
- 图的相关概念
- 网图的邻接矩阵存储以及相关操作 C语言
- 图的邻接表存储以及相关操作 C语言
- 二分图的相关概念
- 图的概念与存储
- 图相关概念,存储方式,应用
- GRAPH --- 图的相关概念整理
- 图的相关概念(备用)
- 1.反射的相关概念图:
- 图的概念、存储结构及遍历
- 图的概念 存储结构和遍历
- 图的概念 存储结构和遍历
- 图的存储以及遍历
- Cinder学习--关于存储的相关概念
- 存储过程的概念以及优缺点是什么?
- Wing(Mac)下载+激活
- Codeforces 330C Purification【思维】
- mybatis bug总结篇
- Codeforces 70D Professor's task [动态凸包]
- Chrome浏览器插件Postman用法简介-Http请求模拟工具
- 【图】图的相关概念以及图的存储
- wifi
- ElasticSearch学习笔记(七)请求的发送
- codeforces 828C. String Reconstruction
- 单机Hadoop的安装与使用
- 乱码过滤器
- 计算文本的宽高
- 【计算机视觉】全景相机
- 玲珑学院 1138 震惊,99%+的中国人都会算错的问题 【容斥】【技巧】