在数据结构中,会涉及到图的几个算法: 最小生成树,拓扑排序,关键路径,从某点到其余点的最短距离。
最小生成数的算法有 Prim(普里姆)算法和Kruskal(克鲁斯卡尔)算法。 从某点到其余点的最短距离是 Dijkstra(迪杰斯特拉)算法。
最小生成树:构造边通网的最小代价的生成树。在构造最小生成树时,利用了其性质:
假设 N=(V, {E})是一个连通网, U是顶点集V的一个非空子集,若(u, v)是一条具有最小权值的边,其中u在U中, v在 V-U中,则必存在一棵包含边(u, v)的最小生成树。(反证法)
普里姆算法:
假设N=(V, {E})是连通网,TE是N上最小生成树中边的集合。算法从U={uo}(uo 在V中) TE={}开始,重复执行以下操作:在所有 u in V, v in V-U 的边, (u,v) in E中找一条代价最小的边(uo, vo) 并入集合TE, 同时vo并入集合U中, 直到 U=V为止。此时TE必有n-1条边,则 T=(V, {TE})为N的最小生成树。
时间复杂度为 O(n^2)
克鲁斯卡尔算法,是以边为出发点,找最小的。对于边稀疏的网,比较适合,时间复杂度为O(eloge)
迪杰斯特拉算法 :给定带权有向图G和源点v, 求从v到G中其余各顶点的最短路径。
按照长度递增的次序寻找。
引进辅助向量 D, D[i]表示当前所找到的从v到vi的最短口路径的长度。它的初态为: 若从v到vi有弧, 则D[i]为弧上的权值;否则置D[i]为无穷大。则D[j] = Min{D[i] | vi in V}
D[j]就是从v出发的长度最短的一条路径。此路径为 (v, vj).
下一条次序短的口含天宪是哪一条?假设该次短路径的终点是vk, 则这条路径或者是(v, vk), 或者是 (v, vj, vk).它的长度或者是从v到vk的弧上的权值,或者是D[j]和从vj到vk的弧上的权值。
时间复杂度为 O(n^2).
看Prim算法和迪杰斯特拉算法,思想上有几分想像。都是从一个顶点出发,把集合分成两部分,已经找到的顶点,以及还没找的顶点。只不过在这两个集合中,找下一个点的依据不同。
迪杰斯特拉算法针对的是有向图,Prim针对的是无向图。