算法导论
阅读《算法导论》的笔记和实验
麦克斯韦的妖精
大槐树下一梦醒,人事功名两茫茫。长恨当年花开日,少不更事老来伤。
展开
-
二叉树的前序、中序、后序遍历的递归与非递归Java实现
二叉树的三种遍历是经常用到的基本操作。递归的写法相对简单,但有时候非递归的实现,却需要想一想。今天,统一思考了一下,并用Java进行了实现,记录在这里,以便脑子宕机的时候看看。一切的递归,都可以用自己写的栈来实现。二叉树节点类:/** * 二叉树节点 */public class TreeNode { public int val; public TreeNode left; public TreeNode right; public TreeNode(int原创 2020-11-02 21:44:46 · 770 阅读 · 0 评论 -
二叉搜索树的Java实现
在二叉搜索树中,对于一个节点 x ,其左子树中所有节点的值都不大于 x 的值,其右子树中所有节点的值都不小于 x 的值。树节点类要实现二叉搜索树,首先需要构造一个 TreeNode 的类,在这个类中 value 属性用于存储节点的值,parent 、leftChild 和 rightChild 分别为其父节点、左孩子节点和右孩子节点。public class TreeNode<T e...原创 2020-04-13 21:08:49 · 285 阅读 · 0 评论 -
堆排序的Java实现
堆排序一种时间复杂度为O(nlogn)O(n\log n)O(nlogn)的原址排序,其实现可以只利用常数级的额外空间。其详细介绍可参考《算法导论》中的介绍。本文主要记录堆排序的Java实现过程。Heap抽象类一般有两种常见的堆的实现方式:最大堆和最小堆。其区别在与根节点是比子节点大还是小。若根节点不小于子节点,则为最大堆,若根节点不大于子节点,则为最小堆。这两种堆的实现方式的区别在与建堆的...原创 2020-04-10 17:13:27 · 220 阅读 · 0 评论 -
计算任意多边形面积的Python实现
最近需要实现一个计算非凸多边形面积的功能,需要输入是顺次排序的多边形顶点坐标,假设输入的多边形顶点是V={v0, v1, v2, …, vn-1},则多边形的边为E={<v0, v1>, <v1, v2>, <v2, v3>,...,<vn-2, vn-1>, <vn-1, v0>}。要求输出该多边形所围成的面积。...原创 2019-02-18 19:56:30 · 10907 阅读 · 5 评论 -
《算法导论》第三版勘误与建议
最近在读由殷建平、徐云、王刚、刘晓光、苏明、邹恒明和王志宏七位老师翻译,机械工业出版社出版的《算法导论(第3版)》这本书,发现了一些不太恰当的地方,在这里进行一下记录,以方便日后再读时查阅。此处按照页码顺序进行排序,由于我现在尚远远没有读完此书,故只能找出已读部分的一些进行整理,日后会不断完善。如有改得不太恰当之处,还请诸位大神不吝留言赐教。第一部分 基础知识第4章 分治策略...原创 2019-01-01 20:41:53 · 2172 阅读 · 0 评论 -
Graham-Scan算法计算凸包的Python代码实现
对于一个点集P来讲,它的凸包就是一个凸多边形Q,其中满足P中的每个点都在Q的边界上或内部。就像下图所示凸包的计算算法有好多种,wiki和算法导论第33章中都有比较详细的介绍,比如下面是算法导论中给出的Graham-Scan算法计算凸包的伪代码。现在网上已经有了好多计算点集凸包的优秀代码,比如这篇文章,作者在文中使用了一个动画来表示了Graham-Scan算法计算凸包的过程,并给出了...原创 2018-12-23 11:21:04 · 9165 阅读 · 14 评论 -
最大子数组问题三种算法的Java代码实现——暴力求解、分而治之、线性方法
这是《算法导论》书中给的一个例子。下图给出了17天的股票价格。第0天的价格是100美元,你可以在此后任何时刻买进股票。人们都希望“低价买进,高价卖出”,并最大化收益。这里就是要求解在哪一天买进,哪一天卖出,可以获得的收益最大。 本文中,给出了暴力求解和分治法两种求解的方法。暴力求解方法就是尝试多有可能的买进卖出组合,找出收益最大的组合。在分而治之的方法中,我们将原问题进行变换。即寻...原创 2017-11-27 23:48:49 · 1197 阅读 · 0 评论 -
Java实现归并排序
归并排序是一种分治的排序方法。分治法的基本思想是将原问题分解为几个规模较小,但是与原问题类似的子问题,分而治之,求解这些子问题,最后将子问题的解合并成原问题的解,当然这个过程需要递归,就是将子问题再分解为子问题,直至可以直接求解。 分治模式在每层递归都有三个步骤:(1)把原问题分解为子问题;(2)分别求解子问题;(3)将子问题的解合并。归并排序完全遵循这个模式,其步骤包括:将待原创 2017-11-27 19:11:39 · 262 阅读 · 0 评论 -
Ford-Fulkerson算法求最大流Java实现
在最大流问题中,我们希望在不违反任何容量限制的情况下,计算出从源结点到汇点的最大流速。对于流网络中的每一个结点,遵守“流量守恒”:除了源结点与汇点之外,流入该结点的速率等于流出该结点的速率。《算法导论》书中所给出的伪代码如下所示:下面是一个求最大流的过程下面是用Java的代码实现:package Ford_Fulkerson;/** * 网络中的边 *原创 2017-07-07 16:31:26 · 3119 阅读 · 0 评论 -
Floyd-Warshall算法求解所有结点对的最短路径问题Java和Python实现
其实求解所有结点对之间的最短路径问题完全可以用调用|V|次Bellman-Ford算法或Dijkstra算法来实现,但是那样肯定效率会比较低下。与前面两个算法基于邻接链表不同,本文所要说的Floyd-Warshall算法是基于邻接矩阵的,当然也可以用邻接链表来实现。假设i与j是图中的两个结点,那么它们之间至多经过k个结点的最短路径代价肯定不小于至多经过k+1个结点的最短路径的代价。由此对于所有...原创 2017-07-07 11:17:07 · 3580 阅读 · 0 评论 -
Bellman-Ford算法求解单源最短路径Java实现
Bellman-Ford算法解决的是一般情况下的单源最短路径问题,在这里,边的权重可以是负值。如果存在一个从源结点可以到达的权重为负值的环路,则算法将还会告诉我们 不存在解决方案,否则算法将给出最短路径和它们的权重。该算法用到了松弛(relaxation)技术。对于每一个结点v来说,我们维持两个属性,一个是v.d,用来记录从源结点s到结点v的最短路径权重的上界,我们称v.d为s到v的最短路径估计。原创 2017-07-06 21:55:02 · 2427 阅读 · 0 评论 -
Dijkstra算法求单源最短路径Java实现
如果所采用的实现方式合适,Dijkstra算法的运行时间要低于前面所说的Bellman_Ford算法,但是Dijkstra算法要求图中没有负边。Dijkstra算法在运行过程中维持的关键信息是一组结点集合S。从源结点s到该集合中每个结点之间的最短路径已经被找到。算法重复从结点集V-S中选择最短路径估计最小的结点u,将u加入到集合S,然后对所有从u发出的边进行松弛(有关松弛操作可见http://bl原创 2017-07-07 10:51:47 · 4377 阅读 · 1 评论 -
Prim算法求解最小生成树的Java实现
上一篇既然提到了Krusal算法,这里就不得不说Prim算法了,这两个算法都是求解最小生成树的经典的贪婪算法。与Krusal算法不同的是,Prim算法在求解过程中始终保持临时结果是一颗联通的树。该算法的伪代码如下//假设网络中至少有一个个顶点设T为所选边的集合,初始化T为空设 TV为已在树中的顶点的集合,置TV={1}令E为网络中的边的集合while(E不为空,并且T 中的边数原创 2017-07-06 21:11:15 · 4210 阅读 · 0 评论 -
Kruskal算法求解最小生成树的Java实现
假设一个无向图共有V(V>1)个顶点,E条边,那么它的最小生成树(如果有的话)有V个顶点,V-1条边。Krusal算法在求解最小生成树的过程中就是不断地选出一条权重最小的边,如果将这条边插入到目前的最小生成树(此时尚未最终形成)中不形成环路,则将其插入,否则再选择次小边重复以上过程,直到最后最小生成树中有V-1条边,则最小生成树求解成功,否则,原图中不包含最小生成树。下面是《算法导论》一书中的原创 2017-07-06 20:39:26 · 2153 阅读 · 0 评论 -
求解有向图的强联通分量的Java实现
有向图的强联通分量(SCC)是一个最大节点集合,在该结点中满足对于任意一个节点对u和v,同时存在从u到v的路径和从v到u的路径。下图便是一个强联通分量的例子,该图中有4个强联通分量。根据强联通分量的定义,不难得出其一个重要的性质,如果将原图转置,在得到的转置图中,其强联通分量是不变的。其实对一个图中的强联通分量进行合并,就是把一个强联通分量看做是一个等价类将这个等价类合并成一个点,亦或原创 2017-07-06 20:22:02 · 725 阅读 · 0 评论 -
基于邻接链表的图的广度优先搜索Java实现
广度优先搜索(BFS)是最简单的图搜索算法之一。给定一个图G=(V,E)和一个源点s,广度优先搜索对图G中的边进行搜索可以发现所有从源结点s到达的所有结点,并且可以计算从源节点s到每个可以到达的结点的最少边数,同时生成一颗“广度优先搜索树”。在《算法导论》一书中,作者用了三种结点的颜色(白色,黑色和灰色)来方便讲解和读者理解。所有的结点在一开始的时候均涂上白色,白色代表尚未发现,灰色代表已经发原创 2017-07-06 19:39:27 · 643 阅读 · 0 评论 -
用栈实现图的深度优先搜索Java实现
《算法导论》一书中给出的深度优搜索是使用递归方式实现的。相比较而言,用递归的方式实现必用非递归方式实现要好理解很多。但是一般而言所有的递归方式实现都可以用非递归方式实现来代替。这里用一个栈结构来代替递归。初始化时将搜索的源节点压入栈中,只要栈不为空,重复以下操作:(1)弹出栈顶元素结点(2)将弹出的栈顶结点的所有邻接后续结点中尚未被发现的结点压入栈中。具体代码实现如下所示/**原创 2017-07-06 19:58:15 · 3506 阅读 · 0 评论 -
Java实现图结构
本学期有一门课程叫做算法分析与设计,用的教材是机械工业出版社的《算法导论》中文版第三版。课程只包括这本书的图算法部分,也就是第22章到第26章的部分,授课老师是郭炅老师,郭老师的水平还是很高的,在这里对郭老师一学期的授课表示感谢。而这几篇关于图算法的博客,就是基于这门课程的实验来进行整理的。我们知道图一般有两种表示方法:邻接链表和邻接矩阵。比如在下图中b与c分别是图a的邻接链表表示和邻接矩阵表原创 2017-07-06 16:59:05 · 2249 阅读 · 0 评论