(一)图的存储与基本操作
1.邻接矩阵表示法 ,可以表示带权图,也可以只用0和1表示是否连通。常用来存储稠密图。
所占空间O(|V|方)
2.邻接表法
顺序结构存储各个定点,每个定点的数据结构中除了包括自己顶点编号,还有一个链表指针,指向自己的连通的节点编号。常用来存储稀疏图。
所占空间O(|V|+|E|)
(二)图的搜索
1.深度优先搜索
借助递归,访问每个节点的时候,将其相邻且未被标记的第一个节点重复进行DFS函数,并加以标记。
时间复杂度:邻接矩阵为O(V方) 邻接表为O(V+E)
空间复杂度:空间复杂度为函数调用栈,最好情况下为O(1)也就是每个顶点都是孤立点,最坏情况为O(V)也就是连通图
2.广度优先搜索
借助队列,每个节点出队列的时候将其所有的未被标记的相邻节点放入队列中,并加以标记。
这样队列输出的结果就是BFS遍历的结果。
时间复杂度:使用邻接矩阵为O|V方|,使用邻接表为O(V+E)
空间复杂度:除了存储的邻接矩阵和邻接表以外,需要借助辅助队列,辅助队列最多为O|V|
(三)图的基本应用
1.最小生成树
生成树的条件:1.包含所有顶点 2.任意两个顶点之间只有一条通路
Prime算法:将点集合分成U和V-U,每次从V-U集合中寻找一个点让它到U集合的代价最小,并将其并入U集合,直到最后U=V。
克鲁斯卡尔算法:重新画一个清空所有顶点之间的边的图(只有点), 将原图中所有边的权值按照从小到大排序,在不产生回路的前提下,依次将每条边加入到新图中。
2.最短路径
1.迪杰特斯拉算法
求得的结果是 知道所有点到点A的最短距离以及到A应该怎么走。
将点集合分成U和V-U,U中起始状态只放一个点(放A),每次从V-U集合中寻找一个点让它到U集合的路径的最短。
计算路径最短的方法为:只借助目前U中有的点和边,计算V-U中的所有的点,与A的距离,(可能不是直接与A相连,需要借助其它顶点与A连接起来),与A的距离最小的点就加入U集合。
需要使用三个数组:
1.final[v_size]数组用于表示是否找到该顶点到A的最短路径了
2.dist[v_size]数组用于表示该顶点到A的最短路径
3.path[v_size]数组用于表示该顶点是借助哪个顶点进入的U
2.弗洛伊德算法
本质是动态规划,map(i,j) = map(i,k)+map(k,j)
o(|V|的三次方)
3.拓扑排序
1.选择没有前驱的顶点输出
2.删除和该顶点有关的边
3.重复1、2
4.关键路径
按照拓扑排序的方法,先找到每个节点最早开始时间,然后再逆着找到每个节点的最晚开始时间。
每个事件(边)的最早开始时间,就是节点的最早开始时间;每个事件的最晚开始时间,就是节点的最晚的开始时间减去该事件的时间。
事件的最早开始时间=最晚开始时间的,即为关键边。