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

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. oc13--pragma mark

    // // main.m // #pragma mark基本使用 // // Created by xiaomage on 15/6/18. // Copyright (c) 2015年 xiaoma ...

  2. PHP中数据类型转换的三种方式

    PHP中数据类型转换的三种方式 PHP的数据类型转换属于强制转换,允许转换的PHP数据类型有: 1.(int).(integer):转换成整形2.(float).(double).(real):转换成 ...

  3. B1567 [JSOI2008]Blue Mary的战役地图 二分答案+hash

    一开始以为是dp,后来看了一下标签...二分答案?之前也想过,但是没往下想,然后之后的算法就顺理成章,先求出第一个地图的所有子矩阵的hash值,然后求第二个,在上一个地图例二分查找,然后就没了. 算法 ...

  4. php打马赛克

    本文实例讲述了php实现图片局部打马赛克的方法.分享给大家供大家参考.具体分析如下: 原理: 对图片中选定区域的每一像素,增加若干宽度及高度,生成矩型.而每一像素的矩型重叠在一起,就形成了马赛克效果. ...

  5. LUA 创建文件和文件夹

    创建文件: os.execute('mkdir e:\\aa') 创建文件夹: os.execute("cd.>e:\\wang.ini")

  6. P1034 矩形覆盖

    题目描述 在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示.例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4(0,7),见图一. 这 ...

  7. hdu2819 Swap 最大匹配(难题)

    题目大意: 给定一个元素的值只有1或者0的矩阵,每次可以交换两行(列),问有没有方案使得对角线上的值都是1.题目没有限制需要交换多少次,也没限制行交换或者列交换,也没限制是主对角线还是副对角线.虽然没 ...

  8. MSSQL数据库设置单用户模式后无法连上解决办法

    设置数据库单用户模式后, 发现用系统管理员账号无法连接数据库, 用sa账号也不行. 首先, 马上去查了一下有什么进程比这个连接给占用了 SELECT [Spid] = session_Id , eci ...

  9. C-Store论文阅读笔记

    C-Store论文由今年的图灵奖获得者Mike Stonebraker提出来,整体架构在数据库领域相当不错.数据库采用读写分开存的架构,只写块的数据定期会和只读块儿的数据进行合并,产生新的只读块儿.而 ...

  10. javascript中函数表达式的问题讨论

    #函数表达式 ##函数声明和函数表达式的区别 函数的定义有两种形式,一种是函数声明,一种是函数表达式 使用声明时,要注意函数声明提升现象,比如说在if语句中使用声明会出错,但是表达式就不存在这个问题 ...