基于快速排序的查找前K个最大数

Posted Blog of Eric Wu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于快速排序的查找前K个最大数相关的知识,希望对你有一定的参考价值。

快速排序

下面是之前实现过的快速排序的代码。

function quickSort(a,left,right){
    if(left==right)return;
    let key=partition(a,left,right);//选出key下标
    if(left<key){
        quickSort(a,left,key-1);//对key的左半部分排序
    }
    if(key<right){
        quickSort(a,key+1,right)//对key的右半部份排序
    }
}
function partition(a,left,right){
    let key=a[left];//一开始让key为第一个数
    while(left<right){//扫描一遍
        while(key<=a[right]&&left<right){//如果key小于a[right],则right递减,继续比较
            right--;
        }
        [a[left],a[right]]=[a[right],a[left]];//交换
        while(key>=a[left]&&left<right){//如果key大于a[left],则left递增,继续比较
            left++;
        }
        [a[left],a[right]]=[a[right],a[left]];//交换
    }
    return left;//把key现在所在的下标返回
}

 

明显我们可以看出快排的思想是每次找到一个基准数,将数组排列成基准数左边的每个数都比基准数大,右边的每个数都比基准数小的序列。 通过这个思想,我们可以稍微修改QuickSort函数,使它变成findKmax函数,使之拥有快速查找前k个最大的数。

基于快速排序思想查找第K大的数

function findKmax(a,k){
    let left=0,right=a.length-1;
    let key=partition(a,left,right);
    let len=a.length-key;
    while(len!=k){
        if(len>k){
            key=partition(a,key+1,right);
        }else{
            key=partition(a,left,key-1);
        }
        len=a.length-key;
    }
    return a[key];
}
function partition(a,left,right){
    let key=a[left];//一开始让key为第一个数
    while(left<right){//扫描一遍
        while(key<=a[right]&&left<right){//如果key小于a[right],则right递减,继续比较
            right--;
        }
        [a[left],a[right]]=[a[right],a[left]];//交换
        while(key>=a[left]&&left<right){//如果key大于a[left],则left递增,继续比较
            left++;
        }
        [a[left],a[right]]=[a[right],a[left]];//交换
    }
    return left;//把key现在所在的下标返回
}

重点是要注意判定边界条件,left,right,k三个都在变,因此需要检验

同理,还可以求第K小的数

function findKmin(a,k){//查找第K小的数
    let left=0,right=a.length-1;
    let key=partition(a,left,right);
    while(key!=k-1){
        if(key>k-1){
            key=partition(a,left,key-1);
        }else{
            key=partition(a,key+1,right);
        }
    }
    return a[key];
}
function partition(a,left,right){
    let key=a[left];//一开始让key为第一个数
    while(left<right){//扫描一遍
        while(key<=a[right]&&left<right){//如果key小于a[right],则right递减,继续比较
            right--;
        }
        [a[left],a[right]]=[a[right],a[left]];//交换
        while(key>=a[left]&&left<right){//如果key大于a[left],则left递增,继续比较
            left++;
        }
        [a[left],a[right]]=[a[right],a[left]];//交换
    }
    return left;//把key现在所在的下标返回
}

 

以上是关于基于快速排序的查找前K个最大数的主要内容,如果未能解决你的问题,请参考以下文章

Top k 问题

快速排序/快速选择算法

查找未排序数组中的最大K数

从海量数据中查找出前k个最小或最大值的算法(java)

快排查找数组中的第K个最大元素

基于快速排序方法改成求第k大的数