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

快速排序

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

function quickSort(a,left,right){
    if(left<right){
        let mid=partition(a,left,right);//选出key下标
        quickSort(a,left,mid-1);//对key的左半部分排序
        quickSort(a,mid+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函数,使它变成QuickSearch函数,使之拥有快速查找前k个最大的数。

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

function quickSearch(a,left,right,k){
    if(k<1||k>right-left+1) return -1;//重点1,当k的值不符合要求时,返回-1
    if(left==right) return a[left];//重点2,递归的结束条件
    let key=-1,len=0;
    if(left<right){
        key=partition(a,left,right);
        len=right-key+1;
        if(len==k){//重点3,递归的结束条件
            return a[key];
        } else if(len>k){
            return quickSearch(a,key+1,right,k);
        } else{
            return quickSearch(a,left,key-1,k-len);
        }
    }
    return 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现在所在的下标返回
}
let arr=[5,4,3,2,1,6];
let kmax=quickSearch(arr,0,5,2);
console.log(kmax);

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

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

运行结果:

原文地址:https://www.cnblogs.com/wuguanglin/p/searchKMax.html

时间: 2024-10-13 02:52:57

基于快速排序的查找前K个最大数的相关文章

在N个数中查找前K个最大数

在N个数中查找前K个最大数,主要利用小堆的特点,小堆,是根节点元素小于左右子树元素,查找前K个最大数,先将N个数中的前K个数生成小堆,接着,依次将N中的剩余的数与小堆的根节点相比,如果大于根节点,则根节点换为这个数,再将堆进行生成小堆,依次直到N中无剩余,代码如下 #define N 10000 #define K 100 void Create(int top[],int parent) { int child = 2 * parent + 1; while (child < K) { if

每日一题:查找前k个最小值

查找前k个最小值最直接的方式是遍历输入数组k遍,每次找出剩下输入中的最小值,每次查找过程中采用交换的策略,这样程序运行结束原数组的前k个数就是按顺序排列的前k个最小数,第二种思路是维护一个具有k个元素的查找树(初始化为输入数组的前k个数),对输入数组的后续每个元素a,将其与查找树的最大数b比较,如果a>=b,则什么也不做,如果a < b,则将b删除,再将a插入到查找树中,如此即可在O(n+klogn)时间内找到输入数组中的前k个最小值.第三种思路是在原数组上运行k遍初始化最小堆算法,第四种思路

在集合中查找前k个最小的数

1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define SIZE 10 5 6 int * k_thSmallest(int * arr, int len, int k_len); 7 8 void find(int* arr, int low, int high, int k_len); 9 10 void swap(int * a, int *b); 11 12 void printArr(int * arr, int le

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

现在有这么一道题目:要求从多个的数据中查找出前K个最小或最大值 分析:有多种方案可以实现.一.最容易想到的是先对数据快速排序,然后输出前k个数字.   二.先定义容量为k的数组,从源数据中取出前k个填充此数组,调整此数组的最大值maxValue到首位,然后对剩下的n-k个数据迭代,对于每个遍历到的数字x,如果x < maxValue,用x把maxValue替换掉,然后调整数组最大值的位置. 三.基于二的思路,维护容量为k的堆,从源数据中取出前k个填充实例化堆,调整此堆中的最大值maxValue到

LeetCode347:返回频率前K高的元素,基于优先队列实现

package com.lt.datastructure.MaxHeap; import java.util.LinkedList; import java.util.List; import java.util.TreeMap; import com.lt.datastructure.Queue.PriorityQueue; /** LeetCode347 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输

若干个(大量)数字中找前K大/小的元素--数值型

方法一:根据快速排序划分的思想 : (1) 递归对所有数据分成[a,b)b(b,d]两个区间,(b,d]区间内的数都是大于[a,b)区间内的数 : (2) 对(b,d]重复(1)操作,直到最右边的区间个数小于100个. 注意[a,b)区间不用划分 :因为[a,b)区间一定小于(b,d]区间: (3) 返回上一个区间,并返回此区间的数字数目. 如果个数大于100,对(b,d]重复(1)操作,直到最右边的区间个数小于100个: 如果个数小于100,对上一区间的左边进行划分,分为[a2,b2)b2(b

算法导论学习之线性时间求第k小元素+堆思想求前k大元素

对于曾经,假设要我求第k小元素.或者是求前k大元素,我可能会将元素先排序,然后就直接求出来了,可是如今有了更好的思路. 一.线性时间内求第k小元素 这个算法又是一个基于分治思想的算法. 其详细的分治思路例如以下: 1.分解:将A[p,r]分解成A[p,q-1]和A[q+1,r]两部分.使得A[p,q-1]都小于A[q],A[q+1,r]都不小于A[q]; 2.求解:假设A[q]恰好是第k小元素直接返回,假设第k小元素落在前半区间就到A[p,q-1]递归查找.否则到A[q+1,r]中递归查找. 3

从一个序列中获取前K大的数的一种方法

这个方法是利用快速排序的.在快速排序中,得到中间元素(pivot)之后,比较中间元素之前的元素个数和K的大小关系,从而确定后面该往哪个方向继续递归.如果中间元素前面的元素个数等于K,那就停止递归过程:如果中间元素前面元素个数小于K,那就再中间元素后面进行递归:否则就往中间元素前面进行递归.这样最终得到的是没有排序的前K大的元素,这样再对前K个元素进行一次真正的快速排序.这样就能得到排好序的前K大元素.我随机生成了一个100000个整型数据的文件进行测试,求前10000个元素.这样做用了0.984

hiho week 37 P1 : 二分&#183;二分查找之k小数

P1 : 二分·二分查找之k小数 Time Limit:10000ms Case Time Limit:1000ms Memory Limit:256MB 描述 在上一回里我们知道Nettle在玩<艦これ>,Nettle的镇守府有很多船位,但船位再多也是有限的.Nettle通过捞船又出了一艘稀有的 船,但是已有的N(1≤N≤1,000,000)个船位都已经有船了.所以Nettle不得不把其中一艘船拆掉来让位给新的船.Nettle思考了很久, 决定随机选择一个k,然后拆掉稀有度第k小的船. 已知