随笔分类 - 话说算法
摘要:从一个顶点到达另一个顶点的成本最小的路径。 我们采用一个一般性的模型,即加权有向图。在加权有向图中,每条有向路径都有一个与之关联的路径权重,它是路径中的所有边的权重之和。这种重要的度量方式使得我们能够将这个问题归纳为 “找到有个顶点到达另一个顶点的权重最小的有向路径”。 单点最短路径。给定一幅加权有
阅读全文
摘要:加权图是一种为每条边关联一个权值或是成本的图模型。这种图能够自然地表示许多应用。在一幅航空图中,边表示航线,权值则可以表示距离或是费用。在这些情形中,最令人感兴趣的自然是将成本最小化。这里用加权无向图模型来解决最小生成树:给定一幅加权无向图,找到它的一棵最小生成树。 图的生成树是它的一棵含有其所有顶
阅读全文
摘要:在有向图中,边是单向的:每条边连接的两个顶点都是一个有序对,它们的邻接性是单向的。许多应用都是天然的有向图,如下图。为实现添加这种单向性的限制很容易也很自然,看起来没什么坏处。但实际上这种组合性的结构对算法有深刻的影响,使得有向图和无向图的处理大有不同。 1.术语 虽然我们为有向图的定义和无向图几乎
阅读全文
摘要:图是由一组顶点和一组能够将两个顶点相连的边组成。 顶点叫什么名字并不重要,但我们需要一个方法来指代这些顶点。一般使用 0 至 V-1 来表示一张含有 V 个顶点的图中的各个顶点。这样约定是为了方便使用数组的索引来编写能够高效访问各个顶点信息的代码。用一张符号表来为顶点的名字和 0 到 V-1 的整数
阅读全文
摘要:如果所有的键都是小整数,我们可以使用一个数组来实现无序的符号表,将键作为数组的索引而数组中键 i 处存储的就是它对应的值。散列表就是用来处理这种情况,它是简易方法的扩展并能够处理更加复杂的类型的键。我们需要用算术操作将键转换为数组的索引来访问数组中的键值对。 使用散列表的查找算法分为两步。第一步是用
阅读全文
摘要:之前讲的二叉查找树在最坏情况下性能还是很低的。平衡查找树能够保证无论如何构造它,它的运行时间都是对数级别。在一棵含有 N 个结点的树中,我们希望树高为 ~lgN,这样我们就能保证所有查找都能在 ~lgN 次比较内结束,就和二分查找一样。但是,在动态插入中保证树的完美平衡的代价太高。我们稍微降低完美平
阅读全文
摘要:对于符号表,要支持高效的插入操作,就需要一种链式结构。但单链表无法使用二分查找,因为二分查找的高效来自于能够快速通过索引取得任何子数组的中间元素,链表只能遍历(详细描述)。为了将二分查找的效率和链表的灵活性结合,需要更复杂的数据结构:二叉查找树。具体来说,就是使用每个结点含有两个链接的二叉查找树来高
阅读全文
摘要:高效检索海量信息(经典查找算法)是现代信息世界的基础设施。我们使用符号表描述一张抽象的表格,将信息(值)存储在其中,然后按照指定的键来搜索并获取这些信息。键和值的具体意义取决于不同的应用。符号表中可能会保存很多键和很多信息,因此实现一张高效的符号表是很重要的任务。 符号表有时被称为字典,有时被称为索
阅读全文
摘要:排序就是将一组数据按照某种逻辑顺序重新排序的过程。排序算法的目的就是将所有元素的主键按照这种逻辑顺序排列。 先编写一个排序算法的基类,后面其他算法可以直接继承: public class BaseSort { public BaseSort() { } public static void Sort
阅读全文
摘要:优先队列 许多应用程序都需要处理有序的元素,但不一定要求它们全部有序,或是不一定要一次就将它们排序。很多情况下是收集一些元素,处理当前键值最大的元素,然后再收集更多的元素,再处理当前键值最大的元素。这种情况下,需要的数据结构支持两种操作:删除最大的元素和插入元素。这种数据结构类型叫优先队列。 这里,
阅读全文
摘要:快速排序是应用最广泛的排序算法,流行的原因是它实现简单,适用于各种不同情况的输入数据且在一般情况下比其他排序都快得多。 快速排序是原地排序(只需要一个很小的辅助栈),将长度为 N 的数组排序所需的时间和 N lg N 成正比。 1.算法 快速排序也是一种分治的排序算法。它将一个数组分成两个子数组,将
阅读全文
摘要:什么是归并?即将两个有序的数组归并成一个更大的有序数组。 什么是归并排序?先将要排序的数组递归地分成两半分别排序,然后将结果归并起来。 归并排序能够保证将任意大小为 N 的数组排序所需的时间和 N logN 成正比;缺点是它所需的额外空间和 N 成正比。 1.原地归并的抽象 实现归并的一种直截了当的
阅读全文
摘要:对于大规模乱序的数组,插入排序很慢,因为它只会交换相邻的元素,因此元素只能一点一点地从数组地一段移动到另一端。希尔排序改进了插入排序,交换不相邻地元素以对数组地局部进行排序,最终用插入排序将局部有序的数组排序。 希尔排序的思想是使数组中任意间隔为 h 的元素都是有序的。这样的数组成为 h 有序数组。
阅读全文
摘要:1.选择排序(冒泡排序) 升序 用第一个元素跟其他元素比较,如果该元素比其他元素,则交换,保证该元素是最小的。然后再用第二个元素跟后面其他的比较,保证第二个元素是除第一个最小的。依次循环,直到整个数组。 /// <summary> /// 选择排序 /// </summary> public cla
阅读全文
摘要:作为程序员,开发完一段代码,实现了某个功能时,有必要知道: 我的程序需要多长时间? 是什么导致我的程序消耗很多内存? 比如,统计或者处理了一大批数据。影响这些问题的因素很多,例如,电脑的性能,数据的性质(值类型和引用类型的区别),使用的算法。想要为这些基础问题提供答案需要通过科学方法。 1. 什么是
阅读全文
摘要:算法的主题思想: 1.优秀的算法因为能够解决实际问题而变得更为重要; 2.高效算法的代码也可以很简单; 3.理解某个实现的性能特点是一个挑战; 4.在解决同一个问题的多种算法之间进行选择时,科学方法是一种重要的工具; 5.迭代式改进能够让算法的效率越来越高效; 1. 动态连通性 动态连接:输入是一对
阅读全文
摘要:把描述和实现算法所用到的语言特性,软件库和操作系统特性总称为基础编程模型。 编写递归代码注意的点: 1. 递归总有一个最简单的情况 —— 方法的第一条语句总是包含 return 的条件语句。 2. 递归调用总是尝试解决一个规模更小的子问题,这样递归才能收敛到最简单的情况。 3. 递归调用的父问题和尝
阅读全文
摘要:许多基础数据类型都和对象的集合有关。数据类型的值就是一组对象的集合,所有操作都是关于添加,删除或是访问集合中的对象。背包(Bag),队列(Quene)和栈(Stack) 它们的不同之处在于删除或者访问对象的顺序不同。 1. API Stack 和 Quene 都含有一个能够删除集合中特定元素的方法。
阅读全文