1、图
概念:比线性表和树更为复杂的数据结构,对于图G=(V,E),可以用两种方法来表示,一种将图作为邻接链表的组合,另一种将图作为邻接矩阵来看待。
上图为无向图
2、邻接矩阵
一个矩阵,一个存储着边的信息的矩阵,而顶点则用矩阵的下标表示。对于一个邻接矩阵M,如果M(i,j)=1,则说明顶点i和顶点j之间存在一条边,对于无向图来说,M (j ,i) = M (i, j),所以其邻接矩阵是一个对称矩阵;对于有向图来说,则未必是一个对称矩阵。邻接矩阵的对角线元素都为0。
(1)由于在有向图中,只需要知道是否有从顶点i发出指向顶点j的边,因此如果顶点i有一条指向j的边,那么g[i][j]就设为1,
否则就设为0(注意这是有向图)。
(2)从邻接矩阵的定义可以推断,无向图的邻接矩阵是对称的;有向图的邻接矩阵是则不具备该性质。
2.邻接链表表示法
邻接矩阵是不错的一种图存储结构,但是,对于边数相对顶点较少的图,这种结构存在对存储空间的极大浪费。因此,找到一种数组与链表相结合的存储方法称为邻接表。
表头向量中每个分量就是一个单链表的头结点,分量个数就是图中的顶点数目;
在边或弧稀疏的条件下,用邻接表表示比用邻接矩阵表示节省存储空间;
在无向图,顶点Vi的度是第i个链表的结点数
在邻接表上容易找出任一顶点的第一个邻接点和下一个邻接点;
3、图的遍历
从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次,这个访问的过程叫做图的遍历(Traversing Graph)。且图的遍历算法是一个比较基础的算法,前面我们介绍的有向无环图的依赖排序(拓扑排序)、关键路径等算法都需要基于该算法。
通常,有两条遍历图的路径:广度优先搜索和深度优先搜索,且对无向图和有向图都适用。
广度优先遍历:
假设从起始点v1开始遍历,首先访问v1和v1的邻接点v2和v3,然后依次访问v2的邻接点v4和v5,及v3的邻接点v6和v7,最后访问v4的邻接点v8。于是得到节点的线性遍历顺序为:v1 -> v2 -> v3 -> v4 -> v5 -> v6 -> v7 -> v8,即示例图中红色箭头线为其广度优先遍历顺序。
深度优先遍历:假设从起始点v1开始遍历,在访问了v1后,选择其邻接点v2。因为v2未曾访问过,则从v2出发进行深度优先遍历。依次类推,接着从v4、v8、v5出发进行遍历。在访问了v5后,由于v5的邻接点都已被访问,则遍历回退到v8。同样的理由,继续回退到v4、v2直至v1,此时v1的另一个邻接点v3未被访问,则遍历又从v1到v3,再继续进行下去。于是得到节点的线性顺序为:v1 -> v2 -> v4 -> v8 -> v5 -> v3 -> v6 -> v7,即示例图中红色箭头线为其深度优先遍历顺序。
参考:https://blog.csdn.net/heyuchang666/article/details/49892809
https://blog.csdn.net/CS33sun/article/details/79109923
https://www.cnblogs.com/zhuozengsi/p/4619616.html
https://blog.csdn.net/luoweifu/article/details/9270895