任何数据结构都可以用顺序存储和链式存储
使用两个数组分别存放顶点信息和边(弧)信息
$$G1.vtxs=[v1, v2, v3, v4]$$
$$G1.arcs=\begin{bmatrix}0 & 1 & 1 & 0 \\ 0 & 0 & 0 & 0 \\0 & 0 & 0 & 1 \\1 & 0 & 0 & 0 \end{bmatrix}$$
$$G2.vtxs=[v1, v2, v3, v4, v5]$$
$$G2.arcs=\begin{bmatrix}0 & 1 & 1 & 0 & 0\\ 1 & 0 & 0 & 0 & 1\\1 & 0 & 0 & 1 & 1 \\0 & 0 & 1 & 0 & 0 \\0 & 1 & 1 & 0 & 0 \end{bmatrix}$$
可以发现都是以左上到右下的轴对称的矩阵
使用数组存储,浪费存储空间
带权的邻接矩阵
权替代1
无限大替代0
为图的每一个顶点创建一个单链表,链表中的结点为依附于顶点的边
对于有向图来说,该邻接表为出边表,它的逆邻接表为入边表
十字链表(有向图)、邻接多重表(无向图)…
DFS和广度优先遍历BFS深度优先遍历无法遍历所有顶点时,可判定该图非连通
优先遍历一个顶点的所有分支,类似树的层次遍历,可以借助队列实现
构建连通网最小代价生成树(即带权)
构造最小生成树的算法:Prin算法和Kruskal算法
Prin算法:从某个顶点开始,选择权值最小的边进行连接,将连起来的顶点作为一个整体,再去寻找其权值最小的边进行连接,但不能形成回路
Kruskal算法:将边按权进行排序,每次只挑选权值最小的进行连接,并且避免回路
Prin算法基于连通的选择,Kruskal算法离散的选择Dijkstra算法可用于求最短路径
在BFS中,借助队列来进行遍历,在Dijkstra算法中,可以借助优先级队列priority queue,priority queue可以通过堆heap来实现
从A开始,加入优先级队列
A出队,将A邻接点BC加入队列,优先级队列会自动将数据排序
C出队作为路径,C的邻接点为BD,B已经在队列中,但还没有访问到,仍然加入队列,而A已经访问过,忽略
注意邻接点的权为路径上的权之和,比如此时B的权为AC的$1$与CB的$2$之和$3$
B出队作为路径,B的邻接点CD,C已经在路径上,忽略
D出队作为路径,D的邻接点CEF,C已经在路径上,忽略
再出队是B和D,他们已经在路径中了,丢弃,所以下一个路径是E
E的邻接点,没有可插入队列的了
队列中的E被丢弃,下一个路径是F,队列中没有元素了,算法结束
将该路径中每个顶点的前驱记录成一个表
A到F的最短路径为ACBDF,长度为10