这一章的正文及思考题部分讲到了快速排序及其几种变形,包括:Hoare快排,
普通快排,随机快排,三数取中快排。
这些快排的区别主要是划分方法PARTITION算法的不同:如何选取主元,划分出的
两部分范围是什么。根据划分出的范围不同,各变形的QUICKSORT有微小的差别。
1. Hoare快排
Hoare划分是最初的版本,与《算法导论》中的划分版本相比,它选取第一个元素A[p]为主元。
划分后的两部分是:A[p..j]和A[j+1..r],主元可能放入某一个之中。
int hoare_partition(int A[], int p, int r)
{int x = A[p];int i = p - 1;int j = r + 1;while (1) {do j--;while (A[j] > x);do i++;while (A[i] < x);if (i < j)swap(A, i, j);elsereturn j;}
}void hoare_quick_sort(int A[], int p, int r)
{if (p < r) {int q = hoare_partition(A, p, r);hoare_quick_sort(A, p, q);hoare_quick_sort(A, q + 1, r);}
}

2. 普通快排
选取最后一个元素A[r]为主元后,j 从头遍历到尾,i 是两范围的分隔。
划分结果为[p, q - 1]和[q + 1, r]。
int partition(int A[], int p, int r)
{int x = A[r];int i = p - 1;int j;for (j = p; j <= r - 1; j++) {if (A[j] <= x) {i++;swap(A, i, j);}}swap(A, i + 1, r);return i + 1;
}void quick_sort(int A[], int p, int r)
{if (p < r) {int q = partition(A, p, r);quick_sort(A, p, q - 1);quick_sort(A, q + 1, r);}
}

3. 随机快排
通过头文件stdlib.h中的rand()方法生成[p, r]之间的随机数作为主元。
rand() % n 将生成 [0, n)之间的随机数。
为了重用partition方法,将选定的主元交换到位置 r。
int randomized_partition(int A[], int p, int r)
{int i = p + rand() % (r - p + 1);     swap(A, i, r);return partition(A, p, r);
}void randomized_quick_sort(int A[], int p, int r)
{if (p < r) {int q = randomized_partition(A, p, r);randomized_quick_sort(A, p, q - 1);randomized_quick_sort(A, q + 1, r);}
}

4. 三数取中快排
每次划分前,从当前子数组里随机取出三个数,取这三个数的中间数作为主元的索引。
int median_partition(int A[], int p, int r)
{int range = r - p + 1;int med1 = p + rand() % range;int med2 = p + rand() % range;int med3 = p + rand() % range;int med  = (A[med1] < A[med2]) ?(A[med2] < A[med3] ? med2 : (A[med1] < A[med3] ? med3 : med1)):(A[med1] < A[med3] ? med1 : (A[med2] < A[med3] ? med2 : med3));swap(A, med, r);return partition(A, p, r);
}void median_quick_sort(int A[], int p, int r)
{if (p < r) {int q = median_partition(A, p, r);median_quick_sort(A, p, q - 1);median_quick_sort(A, q + 1, p);}
}//测试方法int main(void)
{int A[SIZE] = { 2, 8, 7, 1, 3, 5, 6, 4 };print(A, SIZE);//hoare_quick_sort(A, 0, SIZE - 1);//quick_sort(A, 0, SIZE - 1);//randomized_quick_sort(A, 0, SIZE - 1);median_quick_sort(A, 0, SIZE - 1);print(A, SIZE);return 1;
}

转载于:https://www.cnblogs.com/xiaomaohai/archive/2012/02/24/6157861.html

《算法导论》第7章 快速排序 (四种变形)相关推荐

  1. 算法导论 第7章 快速排序 —— 练习还没做,记得补锅

    今天来学习第七章--快速排序. 作为占据一章的排序,快速排序可谓是重量级选手. 实际排序中最好的选择,因为 (1) 其平均性能非常好,期望实践复杂度为 O(n lgn); (2) 可进行原址排序; ( ...

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

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

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

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

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

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

  5. 算法导论中求解时间复杂度的三种方法

    这一章讲的是递归式(recurrence),递归式是一组等式或不等式,它所描述的函数是用在更小的输入下该函数的值来定义的. 本章讲了三种方法来解递归式,分别是代换法,递归树方法,主方法. 1.代换法( ...

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

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

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

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

  8. python整数拆分dp算法_整数拆分问题的四种解法【转载】

    http://blog.csdn.net/u011889952/article/details/44813593 整数拆分问题的四种解法 原创 2015年04月01日 21:17:09 整数划分问题是 ...

  9. 空间曲线曲率算法c语言,第一章第四节空间曲线曲率计算公式及推导.doc

    第一章第四节空间曲线曲率计算公式及推导 空间曲线的曲率定义及 计算公式 引理 设是单位圆周上的向量,即, 设与之间的夹角记为,则有 . 证明 因为 , 所以 . (用解等腰三角形或用余弦定理,得 .) ...

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

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

最新文章

  1. java 做登录跳转404_springboot 访问路径错误跳转到404(实现方法一)
  2. ESXI使用记录---安装vSphere(VCSA)
  3. 你不知道的JavaScript错误和调用栈常识
  4. Java面向对象基础整理
  5. 一个python发包的脚本
  6. 数据挖掘10大算法详细介绍
  7. python拖拽获取文件路径_求助tkinter模块如何获取拖拽文件的内容
  8. iptables的端口范围映射
  9. 每周荐书:SLAM、Vue2、爬虫(评论送书)
  10. TD阵营折大将 芯片商凯明将面临倒闭[转]
  11. 企业级spring-boot案例-自定义Spring Boot Starter
  12. 寒武纪科技 服务器芯片,国内首款人工智能服务器诞生!搭载“寒武纪”芯片,走在世界前列...
  13. 快速学会3DMax高级建模人物骨骼蒙皮
  14. android ping tools,PingTools
  15. 误删除Linux下/etc/shadow文件,linux修改密码出现Authentication token manipulation error的解决办法
  16. java-jar启动jar包
  17. S32Kxxx bootloader之CAN bootloader
  18. 软件测试工程师面试题答案分类详解-深圳某老牌培训机构内部绝密文件!绝密文件!绝密文件!
  19. caged系统pdf_C-TPAT协议自我评估表
  20. Java 常用正则表达式,Java正则表达式,Java身份证校验,最新手机号码校验正

热门文章

  1. PASCAL-VOC2012数据集(vocdevkit、Vocbenchmark_release)详细介绍
  2. R-FCN算法的Caffe实现
  3. python实现将字符串转化为数字(逆序输出)
  4. python验证身份证最后一位数字代表什么_身份证尾数带X的人,是有什么特殊身份吗?看完涨知识了...
  5. python安装nodejs_linux上nodejs安装
  6. 区块链 DAG分布式账本技术 DAG数据结构和基于区块的数据结构的差别 优势
  7. 数据结构和算法——八种常用的排序算法----选择排序
  8. 基于SSM的猫头鹰物流网站
  9. mysql 慢查询及深入调优
  10. maven 包上传到远程库,只上传公共模块,微服务或忽略相关模块不上传