参考这里,提到两种方法,并说第二种好:

http://www.cnblogs.com/qsort/archive/2011/05/09/2041653.html

qsort的每一趟中,选定pivot以后,partition的过程如下:

开始时,ptrLeft,ptrRight分别指向数组两端;

*ptrLeft小于pivot时,向右走;*ptrRight大于pivot时,向左走;

ptrLeft和ptrRight都走不动的时候,交换对应的元素,继续。

ptrLeft和ptrRight相遇的时候,结束这一趟,然后二分的对两边继续qsort。

更新:这样的做法需要处理各种特殊情况(略),因此更好的思路是:

partition的时候,思路是:

1,将pivot放到序列末尾;

2,两个指针ptr_old_curr、ptr_new_curr从左向右扫描,如果*ptr_old_curr <= pivot,就交换到ptr_new_curr位置;换言之,ptr_new_curr一直指向下一个位置;

3,ptr_old_curr到达末尾后,ptr_new_curr指向第一个大于pivot的位置,将pivot放回这个位置即可。

这样的好处是:完全不需要判断各种异常情况。一个实现参见http://www.cnblogs.com/qsort/archive/2011/08/30/2155923.html

查找第k小的数,可以利用qsort中的partition来一次去掉大概一半。

思想如下:Find(k, Left, Right)的时候,先选择一个pivot,来Partition(Pivot, Left, Right)

之后,设Pivot所在位置为Middle,可知Pivot左侧都比Pivot小,右侧都比Pivot大。

如果左侧有大于k个数,那么第k小的数肯定在左侧,可以继续Find(k, Left, Middle)

如果左侧数字小于k个,那么第k小的数肯定在右侧,而且是右侧的第 (k - (Middle - Left + 1) )个数,可以继续Find([k - (Middle - Left + 1)], Middle, Right)了。

 
 

快速排序、查第k大的更多相关文章

  1. 快速排序 && 寻找第K大(小)的数

    参考:https://minenet.me/2016/08/24/quickSort.html 快速排序 利用分治法可将快速排序的分为三步: 在数据集之中,选择一个元素作为"基准" ...

  2. 树状数组+二分答案查询第k大的数 (团体程序设计天梯赛 L3-002. 堆栈)

    前提是数的范围较小 1 数据范围:O(n) 2 查第k大的数i:log(n)(树状数组查询小于等于i的数目)*log(n)(二分找到i) 3 添加:log(n) (树状数组) 4 删除:log(n) ...

  3. POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]

    The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8807   Accepted ...

  4. POJ 2985 The k-th Largest Group(树状数组 并查集/查找第k大的数)

    传送门 The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8690   Acce ...

  5. 基于快速排序思想partition查找第K大的数或者第K小的数。

    快速排序 下面是之前实现过的快速排序的代码. function quickSort(a,left,right){ if(left==right)return; let key=partition(a, ...

  6. 寻找第K大的数(快速排序的应用)

    有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数.给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在.测试样例:[1,3,5,2,2],5, ...

  7. 快速排序算法的实现 && 随机生成区间里的数 && O(n)找第k小 && O(nlogk)找前k大

    思路:固定一个数,把这个数放到合法的位置,然后左边的数都是比它小,右边的数都是比它大 固定权值选的是第一个数,或者一个随机数 因为固定的是左端点,所以一开始需要在右端点开始,找一个小于权值的数,从左端 ...

  8. Coursera Algorithms week3 快速排序 练习测验: Selection in two sorted arrays(从两个有序数组中寻找第K大元素)

    题目原文 Selection in two sorted arrays. Given two sorted arrays a[] and b[], of sizes n1 and n2, respec ...

  9. luogu_P1177 【模板】快速排序 (快排和找第k大的数)

    [算法] 选取pivot,然后每趟快排用双指针扫描(l,r)区间,交换左指针大于pivot的元素和右指针小于pivot的元素,将区间分成大于pivot和小于pivot的 [注意] 时间复杂度取决于pi ...

随机推荐

  1. h5-10 canvas 简易祖玛

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. Connect the Cities--hdoj

    Connect the Cities Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) ...

  3. 南海区行政审批管理系统接口规范v0.3(规划)4.1.【queryAcceptById】业务明细查询

    加密前:{"time":"1510061005493","username":"GH_DATA_EXCHANGE",&q ...

  4. php 日期格式化

    date('Y-m-d H:i:s',time()); 2014-09-01 05:06:01 date(' y-n-j G:i:s',time()); 14-9-1 5:06:01 mktime(h ...

  5. 【BZOJ3218】【UOJ#77】a + b Problem

    题目 题目在这里 思路&做法 明显的最小割(其实是之前做过一道类似的题) S向每一个格子连容量为\(b_i\)的边 每一个格子向T连容量为\(w_i\)的边 对于格子\(i\)向满足条件的格子 ...

  6. python之路——二分查找算法

    楔子 如果有这样一个列表,让你从这个列表中找到66的位置,你要怎么做? l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72 ...

  7. c语言open()介绍

    2013-09-0914:40:13 1. 头文件: #include <sys/types.h> #include <sys/stat.h> #include <fcn ...

  8. SQLServer int转float

    例: select 2/4  会得到0 改为 select 2/4.0 则会得到0.500000 也同时达到了int转float的效果

  9. call by value 和 call by reference 的区别

    引用自https://zhidao.baidu.com/question/340173099.html Call by Value就是传值的方式,函数调用时是把实参的值传给形参,函数调用结束后形参的值 ...

  10. Qwt--散点图/函数图

    1.Qwt库 QwtPlot是用来绘制二维图像的widget.在它的画板上可以无限制的显示绘画组件.绘画组件可以是曲线(QwtPlotCurve).标记(QwtPlotMarker).网格(QwtPl ...