随笔分类 - 算法与数据结构
摘要:本文给出了对于《算法(第4版)》(以下简称原书或书)中的练习题 3.3.20 的一种解法。 ◆ 要求 原书中的练习题 3.3.20 要求计算一棵大小为 N 且完美平衡的二叉查找树的内部路径长度,其中 N 为 2 的幂减 1。 ◆ 解答 N 为 2 的幂减 1 的一颗完美平衡的二叉查找树是一棵满二叉树
阅读全文
摘要:本文记述了二叉树的基本概念、表示法、性质和操作。 ◆ 概念 二叉树(以下也简称树)是一种存放多个元素的数据结构。每个元素称为结点,每个结点有左、右两个链接,每个链接要么指向其他结点,要么是空链接。 某个结点是它的左、右链接指向的结点的父结点,被指向的结点是其父结点的左或右子结点。没有父结点的结点称为
阅读全文
摘要:本文汇总了笔者所写的所有“常见的排序算法”的实现,从性能特点和运行时间的角度加以了对比。 以下表格记录了笔者所写的所有“常见的排序算法”的性能特点。 算法类 时间复杂度 空间复杂度 是否稳定 备注 Selection N^2 1 否 选择排序 Insertion N^2 1 是 插入排序,标准版。
阅读全文
摘要:本文记述了堆排序算法改用多叉堆实现的基本思想和一份参考实现代码,并在说明了算法的性能后用随机数据进行了验证。 ◆ 思想 多叉堆的完全树中,位置为 k 的结点,其父结点的位置为 ⎣(k + (d-2)) / d⎦,其子结点的位置为 k*d - (d-2), k*d - (d-1), ..., k*d,
阅读全文
摘要:本文记述了堆排序改用前序表示法基本思想和一份参考实现代码,并在说明了算法的性能后用随机数据进行了验证。 ◆ 思想 堆排序算法按照层次操作堆中的元素,即物理位置 k 的结点与位置 2k 或 2k+1 的结点交换。然而用前序表示的堆,其父子结点的位置关系不能简单地计算出来。因此,当算法模型(逻辑上)用的
阅读全文
摘要:本文记述了针对堆排序同时实施减少数据交换和 Floyd 方法的一份参考实现代码,并在说明了算法的性能后用随机数据进行了验证。 ◆ 思想 减少数据交换的操作,请参考堆排序(二);Floyd 方法,请参考堆排序(三)(此处略去详细说明)。 ◆ 实现 排序代码采用《算法(第4版)》的“排序算法类模板”实现
阅读全文
摘要:本文记述了针对堆排序实施 Floyd 方法的基本思想和一份参考实现代码,并在说明了算法的性能后用随机数据进行了验证。 ◆ 思想 “大多数在下沉排序期间重新插入堆的元素会被直接加入到堆底。Floyd 在 1964 年观察发现,我们正好可以通过免去检查元素是否到达正确位置来节省时间。”(引《算法(第4版
阅读全文
摘要:本文记述了针对堆排序微小改动的基本思想和一份参考实现代码,并在说明了算法的性能后用随机数据进行了验证。 ◆ 思想 堆的下沉操作中用到了昂贵的数据交换操作,此改动参考无交换的插入排序的思想,实现了减少数据交换的下沉操作。 先将要下沉的元素存放在临时空间中,再将下降过程中遇到的所有元素逐层上移,待找到下
阅读全文
摘要:本文记述了堆排序的基本思想和一份参考实现代码,并在说明了算法的性能后用随机数据进行了验证。 ◆ 思想 J.W.J Williams 提出了堆排序的算法,该算法利用了二叉堆有序的性质,将排序的过程分为先构建堆再排序的两个阶段。 先构建堆。从当前待排序范围一半的位置开始向第一个位置扫描,用下沉操作处理每
阅读全文
摘要:本文记述了堆的基本概念、表示法和操作。 ◆ 概念 堆是一种存放多个元素的数据结构,它要求每个元素都要大于等于或小于等于另外若干特定位置的元素。堆常用完全 d 叉树(以下简称“完全树”)表示,堆中的元素与树上的结点一一对应,这样的完全树是堆有序的,也被称为 d 叉堆。当完全树的每个结点都大于等于它的所
阅读全文
摘要:本文记述了非递归快速排序的基本思想和一份参考实现代码,并在说明了算法的性能后用随机数据进行了验证。 ◆ 思想 非递归的快速排序,使用一个栈保存待排序子范围的范围边界。在循环中弹出栈顶的范围边界。使用切分函数找到此范围中一个切分位置,保证其左侧子范围内的所有元素都不大于切分位置的元素,右侧子范围内的所
阅读全文
摘要:本文记述了 J.Bently 和 D.Mcllroy 的快速三向切分快速排序的基本思想和一份参考实现代码,并在说明了算法的性能后用随机数据进行了验证。 ◆ 思想 对比快速排序、快速排序(二)和快速排序(三)可以发现,对于随机数据而言,E.W.Dijkstra 的三向切分快速排序的性能要慢于标准快速排
阅读全文
摘要:本文记述了 E.W.Dijkstra 的三向切分快速排序的基本思想和一份参考实现代码,并在说明了算法的性能后用随机数据进行了验证。 ◆ 思想 “在有大量重复元素的情况下,快速排序的递归性会使元素全部重复的子数组经常出现。这就有很大的改进潜力,将当前实现的线性对数级的性能提高到线性级别。”(引《算法(
阅读全文
摘要:本文记述了对快速排序的 2 项改进的基本思想和一份参考实现代码,并在说明了算法的性能后用随机数据进行了验证。 ◆ 思想 本文实现了《算法(第4版)》书中提到的 2 项改进, 切换到插入排序:对小规模子数组使用插入排序。减少在小规模数组中的递归调用能改进整个算法。 三取样切分:将取样大小设为 3 并用
阅读全文
摘要:本文记述了快速排序的基本思想和一份参考实现代码,并在说明了算法的性能后用随机数据进行了验证。 ◆ 思想 基于分治思想的快速排序,使用切分函数找到一个切分位置,保证其左侧子范围内的所有元素都不大于切分位置的元素,右侧子范围内的所有元素都不小于切分位置的元素。然后用递归调用分别对两个子范围排序。 算法的
阅读全文
摘要:本文记述了多向归并排序的基本思想并给出了一份参考实现代码。在说明了算法的性能后用随机数据进行了验证。 ◆ 思想 在归并排序、归并排序(二)、归并排序(三)、归并排序(四)中记述的归并排序,都是把待排序范围分成两个部分分别排序的。而多向归并排序是把待排序范围分为 K 个部分,把它们分别排序然后进行归并
阅读全文
摘要:本文记述了自然的两两归并排序并给出了一份参考实现代码。在说明了算法的性能后用随机数据进行了验证。 ◆ 思想 自然的归并排序是自底向上的。先从第一个元素开始找到一个有序的子范围,然后从紧接着的后面元素开始找到另一个有序的子范围,将这两个子范围归并成一个大的有序子范围。接着找到下一个有序子范围,将它与前
阅读全文
摘要:本文记述了针对归并排序的 3 项改进和一份参考实现代码,并在说明了算法的性能后用随机数据进行了验证。 ◆ 思想 本文实现了《算法(第4版)》书中提到的 2 项改进和练习题 2.2.10。 对小规模子数组使用插入排序。因为递归会使小规模问题中方法的调用过于频繁,所以改进对它们的处理方法就能改进整个算法
阅读全文
摘要:本文记述了针对归并排序的 3 项改进和一份参考实现代码,并在说明了算法的性能后用随机数据进行了验证。 ◆ 思想 本文实现了《算法(第4版)》书中提到的 3 项改进, 对小规模子数组使用插入排序。减少在小规模数组中的递归调用能改进整个算法。 测试数组是否已经有序。任意有序的子数组算法的运行时间变成线性
阅读全文
摘要:本文记述了自底向上归并排序的基本思想和一份参考实现代码,并在说明了算法的性能后用随机数据进行了验证。 ◆ 思想 使用自底向上的递推思想进行排序。从大小为 1 的子范围开始两两归并,得到小规模排序的结果。逐步将子范围的大小翻倍并继续两两归并,直到整个数组范围都已被归并,即得到整体排序的结果。归并两个已
阅读全文