数据结构----图
前言
学习数据结构的时候,经常存在这样一个问题,为什么有这么多的数据结构,有一种不就行了吗?假如数据结构是不断发展的,那怎么学习最好的那种结构不就行了?解释一下
1:我们学习的时候要知道前因后果,要知道牛X的数据结构是怎么样来的;
2:并非最新的数据结构是最好的数据结构,它可能适合特定场景,到另外一个场景就不够用了,比如一个耗时但省空间,另一个相反。
1 图的数据结构
图的数据结构一般有四种表达方式:邻接矩阵,邻接表,十字链表,邻接多重表。
1.1 邻接矩阵:(适合有向图和无向图)
说明:邻接矩阵是最简单,也最能想到的存图的数据结构,定点用一维数组表示,边用二维数组(矩阵)表示,0表示两点之间没有连接线,1表示两点之间有连接线。适合有向图和无向图。
存放顶点的数组(G.vexs):
V1 | V2 | V3 | V4 | V5 | V6 | V7 |
---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 |
存放边的矩阵(G.arcs):
1.2 邻接表:(适合有向图和无向图)
说明:邻接矩阵的表示方式,比较占空间,就算两条边之间没有相连的线,也会占内存空间。假设图有n个顶点,那么邻接矩阵需要n*n条边来存储这个图。这个时候,邻接表就能很好的解决这个问题。两点之间有连接线才会存储,才会占用内存。
邻接表:在垂直方向上,首先将顶点组成一个数组,在水平方向上,每个顶点和边又组成一个单链表。所以这个单链表的表头就是顶点
存放顶点的结构(G.vexs):
data | firstarc(指向下一个边节点) |
---|
存放边的结构(G.arcs):
adjvex(和表头有关系的邻接点) | nextarc(指向下一个边节点) |
---|
邻接表的表示方式:
1.3 十字链表:(针对邻接表改的,适合有向图)
说明:因为邻接表只能找到出度,不能找到入度,所有改进一下,把邻接表改成十字链表。
注:有向图才有出度和入度,出度就是以该点为起点的边的条数,入度是以该点为终点的边的条数。无向图只有度这么一个概念
存放顶点的结构(G.vexs):
顶点表: (数据)+(指向以该顶点为弧头的第一个弧节点)+(指向以该顶点为弧尾的第一个弧节点)
即:(数据)+(进来的第一条弧)+(出去的第一条弧)
data | firstIn | firstOut |
---|
存放边的结构(G.arcs):
data | headVex | hLink | tLink |
---|
十字链表表示方式:
以A节点为例,A节点对应两个链表(绿色和黄色的),绿色链表表示以节点A为弧头的弧组成的链表,黄色链表表示以节点A为弧尾的弧组成的链表。
注:如果有一条边(a—>b),则b是弧头,a是弧尾。
1.4邻接多重表:(针对邻接表改的,适合无向图)
邻接多重表,是在邻接表的基础上改进的,因为十字链表是适合有向图的,所以需要一个数据结构适合无向图,也就是邻接多重表。
我们发现,在无向图邻接表中,边节点存在冗余,也就是说,我们在无向图的邻接表中能找到一条边有两个边节点(A-B和B-A)。如果我们要删除的时候,还得遍历全部顶点和边,很不方便。
存放顶点的结构(G.vexs):
顶点表: (数据)+(依附顶点的第一条边)
data | firstedge |
---|
存放边的结构(G.arcs):
边表:
| ivex:表示
ivex | ilink | jvex | jlink |
---|
ivex:起点
ilink:终点
hLink:表示指向弧头相同的下一条弧
tLink:表示指向弧尾相同的下一条弧
邻接多重表表示方式:
总结
总体流程可以用下图表示。
1:引用了网上很多人的博客(图片),找不到出处了,没有列出出处,若侵权请联系我删除。
2:可能我对数据结构中图的理解不够,欢迎指导