今天来学习第七章——快速排序。

作为占据一章的排序,快速排序可谓是重量级选手。

  • 实际排序中最好的选择,因为

    • (1) 其平均性能非常好,期望实践复杂度为 O(n lgn);
    • (2) 可进行原址排序;
    • (3) 在虚拟环境中也能很好地工作。
  • 适用于基于随机的数据,因为其最坏情况时间复杂度为 n^{2}。最坏情况即所有元素都一样。

1. 概念

2. 伪代码

QUICKSORT(A, p, r)
if p < rq = PARTITION(A, p, r)QUICKSORT(A, p, q - 1)QUICKSORT(A, q + 1, r)PARTITION(A, p, r)
x = A[r] // pivot element, 主元
i = p - 1
for j = p to r - 1 // 无限制区域元素划分if A[j] <= xi = i + 1exchange A[i] with A[j]
// 循环结束后,修改主元与中间元素。
// 这一步操作使得在主元 A[p] 左边的元素都比主元小,在主元 A[p] 右边的元素都比主元大。
exchange A[i + 1] with A[r]
return i + 1

为了排序一整个数组,一开始调用的函数是 QUICKSORT(A, 1, A.length)

以下则是上述函数维护的数组图像表示:

3. Java 实现

public class QuickSort {public static void main(String[] args) {int len = 10;int[] a = new int[len];for (int i = 0; i < len; i++) {a[i] = (int)(Math.random() * 100);}// 排序之前for (int num: a) {System.out.print(num + "\t");}quickSort(a, 0, len - 1);// 排序之后System.out.println();for (int num: a) {System.out.print(num + "\t");}}public static void quickSort(int[] a, int p, int r) {if (p < r) {int q = partition(a, p, r);quickSort(a, p, q - 1);quickSort(a, q + 1, r);}}public static int partition(int[] a, int p, int r) {int x = a[r]; // 主元int i = p - 1;for (int j = p; j < r; j++) {// 无限制区域if (a[j] <= x) {i++;change(a, i, j);}}change(a, i + 1, r);return i + 1;}public static void change(int[] a, int first, int second) {int tmp = a[first];a[first] = a[second];a[second] = tmp;}
}

某一次运行结果如下

65 10 95 21 22 72 95 22 32 31
10 21 22 22 31 32 65 72 95 95

4. 复杂度

以下引用来自 算法复杂度分析

实际中,我们一般仅考量算法在最坏情况下的运行情况,也就是对于规模为 n 的任何输入,算法的最长运行时间。这样做的理由是:
(1) 一个算法的最坏情况运行时间是在任何输入下运行时间的一个上界(Upper Bound)。
(2) 对于某些算法,最坏情况出现的较为频繁。
(3) 大体上看,平均情况通常与最坏情况一样差。

渐近记号(Asymptotic Notation)通常有 O、 Θ 和 Ω 记号法。
Θ 记号渐进地给出了一个函数的上界和下界,
当只有渐近上界时使用 O 记号
当只有渐近下界时使用 Ω 记号
尽管技术上 Θ 记号较为准确,但通常仍然使用 O 记号表示。
使用 O 记号法(Big O Notation)表示最坏运行情况的上界。例如,
线性复杂度 O(n) 表示每个元素都要被处理一次。
平方复杂度 O(n^2) 表示每个元素都要被处理 n 次。

在算法导论中,采用记号 lg n = log2 n ,也就是以 2 为底的对数。

下图源于 各个排序算法的时间复杂度和稳定性,快排的原理

5. 练习题(不想做啊,好难啊

7.1-2 当数组 A[p… r] 中的元素都相同时,PARTTION 返回的 q 值是什么? 修改 PARTITION, 使得当数组 A[p… r] 中所有元素的值都相同时,q=⌊(p+r)/2」。

① 当元素相同时, 返回值 q =i+1=r-1+1=r.
② 修改思路:TODO

7.1-3 请简要地证明:在规模为n的子数组.上,PARTITION的时间复杂度为日(n)。

TODO

7.1-4 如何修改QUICKSORT,使得它能够以非递增序进行排序?

TODO

7.2-1 利用代人法证明:正如7.2节开头提到的那样,递归式T(n)= T(n - 1) +0(n)的解为 T(n)=O(n^2 )。
7.2-2 当数组A的所有元素都具有相同值时,QUICKSORT的时间复杂度是什么?
7.2-3 证明:当数组A包含的元素不同,并且是按降序排列的时候,QUICKSORT的时间复杂度为 O(n2 )。
7.2-4 银行一般会按照交易时间来记录某一账户的交易情况。但是,很多人却喜欢收到的银行对账单是按照支票号码的顺序来排列的。这是因为,人们通常都是按照支票号码的顺序来开出支票的,而商人也通常都是根据支票编号的顺序兑付支票。这一问题是将按交易时间排序的序列转换成按支票号排序的序列,它实质上是-一个对几乎有序的输人序列进行排序的问题。请证明:在这个问题上,INSERTION-SORT的性能往往要优于QUICKSORT?
7.2-5 假设快速 排序的每一层所做的划分的比例都是1-a: a,其中0<a≤1/2且是一个常数。试证明:在相应的递归树中,叶结点的最小深度大约是 -lgn/ lga,最大深度大约 -lgn/lg(1- a) (无需考虑整数舍人问题)。
*7.2-6 试证明:在一个随机输人数组上,对于任何常数0<a≤1/2,PARTITION产生比1-a: a更平衡的划分的概率约为1 - 2a。

算法导论 第7章 快速排序 —— 练习还没做,记得补锅相关推荐

  1. 位向量(bit vector)(算法导论第十一章11.1-2)

    位向量(bit vector) 位向量(bit vector)是一个仅包含0和1的数组.长度为m的位向量所占空间要比包含m个指针的数组少得多.说明如何用一个位向量来表示一个包含不同元素(无卫星数据)的 ...

  2. 假设一动态集合S用一个长度为m的直接寻址表T来表示。请给出一个查找S中最大元素的过程。(算法导论第十一章11.1-1)

    假设一动态集合S用一个长度为m的直接寻址表T来表示.请给出一个查找S中最大元素的过程.你所给的过程在最坏情况下的运行时间是多少. (算法导论第十一章11.1-1) #include "Key ...

  3. 算法导论第2章(3) 二分查找 binary search

    二分查找(分治法). 二分查找也是一种分治法的实现,每一次查找将数据分为两个部分,问题规模都减小一半.这样查找的时间复杂度为logN.因为其实查找过程建立了一棵有N个节点的二叉树,查找次数是这棵树的高 ...

  4. 【转载】突然觉得今年的时间过得太快了,不知不觉中还剩下四个多月就步入2017年了,回首一下,好像什么都还没做呢。...

    2019独角兽企业重金招聘Python工程师标准>>> 突然觉得今年的时间过得太快了,不知不觉中还剩下四个多月就步入2017年了,回首一下,好像什么都还没做呢. 在职场的时候,天天盼 ...

  5. Suzy找到实习了吗 | 字符串结束啦 今天学习kmp 题还没做!!!记得回来补!!!

    kmp 看完了kmp的讲解视频 还没做题,跳过了 先占坑 再来补!!!!

  6. 算法导论第十三章 红黑树

    写在前面:这一章真的把我害惨了,之前至少尝试看过3遍,每次看之前都下定决定一定要把它拿下,可是由于内容较多,深度够深,以致于每次要不是中途有什么事放弃了就跳过了,要不是花时间太多仍然不能理解而放弃.这 ...

  7. 重读《算法导论》第一章

    重读<算法导论> --------算法是程序的灵魂! 驱动力:本人从事开发10年有余,目前正在参与研发自动化编程.在代码解析.自动生成.以及源码分析过程中总会遇到一些算法的问题. 所以想着 ...

  8. 算法导论第16章练习题 16.1-4

    16.1-4 假设有一组活动,我们需要将它们安排到一些教室,任意活动都可以在任意教室进行.我们希望使用最少的教室来完成活动.设计一个高效的贪心算法,求每个活动应该在哪个教室来进行. (这个问题也被称为 ...

  9. 我有一个顶会idea还没做实验,NeurIPS:先占坑再实验!

    作者 | 青 暮 相信大家对费马大定理都不陌生,x^n +y^n=z^n.一个简单无比的方程式却是难到几百年后才被数学家解决.而这其中最令人着迷的,当属费马当年在手稿留下的一句话:我这里有一个绝妙的证 ...

最新文章

  1. ORACLE_LOADER加载外部数据
  2. Taran 缩点【bzoj1529】[POI2005]ska Piggy banks
  3. python package安装包_安装Python包(第三方库)
  4. python变量类型之间转换_Python常用数据类型之间的转换总结
  5. 新年+情人节礼物,WinDBG找出你内存溢出的地方
  6. 设计模式的皇后-观察者模式
  7. 剑指OFFER之包含min函数的栈(九度OJ1522)
  8. 第一次注册苹果开发者账号
  9. 理解条件随机场(转)
  10. email 邮件发送源代码(c++实现)
  11. 漫画:面试过程的神回复
  12. 计算机不能识别华为手机,华为手机链接电脑无法识别是为什么?
  13. 中继器有何作用?它的工作原理是什么?-道合顺大数据Infinigo
  14. 日内交易的7大关键点
  15. 【CodeForces】 106C Buns(多重背包)
  16. ubuntu系统损坏修复_修复损坏的ubuntu gui
  17. 如何在virtualBox中安装MacOs教程
  18. Datatable 列名
  19. JavaBeans教程
  20. 怎么使用PS一键抠图?

热门文章

  1. EnCase Computer Forensics, includes DVD: The Official EnCE: EnCase Certified Examiner Study Guide
  2. 优秀的简历模版(给你们准备好了)
  3. Latex输入罗马数字的最简便方法
  4. chrome在新标签页打开_如何使用Google Chrome在计算机之间同步打开的标签页
  5. 使用-XX:+PrintCommandLineFlags展示JVM启动参数
  6. TCP 拥塞控制算法 1
  7. 基于ssm的课程思政资源众包系统的设计与实现毕业设计源码020838
  8. 如何自学软件测试呢?软件测试工程师的职位要求
  9. d3007(d3007经过站点和时间)
  10. 制作一台计算机需要多少知识,如何制造一台计算机,编程多年后我开始思考这个问题...