讲在前面的话,图的算法太多,理论知识肯定一篇文章讲不完,关于理论知识大家可以参考教材Sedgewick的《算法》或reference的链接,本文主要还是想在一篇文章中记录六种算法的Python代码。同样想吐槽一下,虽然网上博客很多,但是并不代表他们的代码都是正确的,还是要看经典教材啊,教材这么多人在用,所以出现错的概率会低一些。在这讲一下自己对这些算法的核心思想的一些个人理解,很多东西细节是记不住的,本科学了两遍算法,现在不也一样重头再学么,但算法的核心思想这是可以记住的,希望我的理解对别人会有一点点用处。
1.个人的一点理解
对于DFS和BFS,如果遇到搜索和遍历,肯定要想到堆栈和队列,而遇到堆栈肯定就要想到是不是可以用递归来实现,因为递归程序其实就是函数在内存中的出栈入栈,DFS就是使用堆栈或者递归来实现,而类似层次遍历的BFS自然就可以使用队列来实现,这跟树的前序,中序,后序遍历(具体参考我之前的一篇博客)和层次遍历的思想是一样的。
对于最短路径算法的Dijkstra、Floyd算法,Dijkstra算法是求从某个源点到其余各个顶点的最短路径(单源最短路径),时间复杂度为
对于最小代价生成树的Prim、Kruskal算法,两种算法的主要核心思想是贪心算法。Prim算法是从任意一个顶点开始,每次选择一个与当前顶点集最近的一个顶点,并将两顶点之间的边加入到树中,其实就是说在当前顶点集所可以辐射到的边中选择最小的一条边(需要判断该边是否已经在最小生成树中),其实就是一个排序问题,然后贪心选取最小值。Kruskal算法则是另外一种思维,选择从边开始,把所有的边按照权值先从小到大排列,接着按照顺序选取每条边(贪心思想),如果这条边的两个端点不属于同一集合,那么就将它们合并,直到所有的点都属于同一个集合为止,其实就是基于并查集的贪心算法。两种算法各有不同,Prim算法的时间复杂度为
2.show me the code
DFS、BFS
graph
Dijkstra、Floyd算法
Prim、Kruskal算法
"""
reference
1.算法(第4版) [美] Robert Sedgewick,[美] Kevin Wayne 著,谢路云 译
2.图解Dijkstra算法和Floyd算法 (看图就好)
3.Dijkstra 最短路算法
4.图解 Prim、Kruskal算法
5.最小生成树之Kruskal算法
6.并查集