获取第K大的数

  1. 使用快速排序,从数组中随机找出一个元素X,把数组分成比X小和比X大的两部分,假设比X小的部分元素个数为B,则:

    (1)   如果B >= K,则递归从比X小的部分找第K大的元素。

    (2)   如果B < K,则递归从比X大的部分找第(K-B)大的元素。

  2.

        (1)  使用最小堆,类似笔试题中O(NlogM)的算法。

(2)   使用最大堆,类似于笔试题中O(MlogN)的算法。

 

int getparent(int begin,int end,int index){
    int parentindex = (index-begin-1)/2+begin;
    return parentindex;
}
int getlchild(int begin,int end,int index){
    int lchildindex = (index - begin) * 2 + 1 + begin;
    return lchildindex;
}
int getrchild(int begin,int end,int index){
    int rchildindex = (index - begin) * 2 + 1 + begin + 1;
    return rchildindex;
}
void adjustheap(vector<int> & v,int begin,int end,int index){
    int lchild = getlchild(begin,end,index);
    int rchild = getrchild(begin,end,index);
    int largest = index;
    if( rchild <= end && v[rchild] > v[largest] )
        largest = rchild;
    if( lchild <= end && v[lchild] > v[largest] )
        largest = lchild;

    if(largest != index){
        int temp = v[largest];
        v[largest] = v[index];
        v[index] = temp;
        adjustheap(v,begin,end,largest);
    }
//    show(v,begin,end);
}
void buildmaxheap(vector<int> & v,int begin,int end){
    int parent = getparent(begin,end,end);
    while(parent >= begin){
        adjustheap(v,begin,end,parent);
        parent--;
    }
}
void heapsort(vector<int> & v,int begin,int end){
    buildmaxheap(v,begin,end);
//    show(v,begin,end);
    int tempend = end;
    for( ; tempend > begin; ){
        int temp = v[begin];
        v[begin] = v[tempend];
        v[tempend] = temp;
        adjustheap(v,begin,--tempend,begin);
    }
}
int getKmaxbyheapsort(vector<int> & v,int begin,int end,int K){  //这个跟完全堆排序步骤是差不多的,不过步骤循环次数有减少了
    buildmaxheap(v,begin,end);
    int i = 0 ;
    int temp = 0;
    for( ; i < K ; i++){
        temp = v[begin];
        v[begin] = v[end];
        v[end] = temp;
        adjustheap(v,begin,--end,begin);
    }
    return temp;
}

//类似快速排序的方式

int partition(vector<int> & v,int begin,int end){
    int key = v[begin];
    int i = begin;
    int j = end;
    while(i<j){
        while(j>i && v[j] <= key)
            j--;
        while(j>i && v[i] > key)
            i++;
        int temp = v[j];
        v[j] = v[i];
        v[i] = temp;
    }
    v[i] = key;
    return i;
}

void quicksort(vector<int> & v,int begin,int end){
    if(begin < end){
        int mid = partition(v,begin,end);
        quicksort(v,begin,mid-1);
        quicksort(v,mid+1,end);
    }
}

int getKmaxbyQuicksort(vector<int> & v,int begin,int end,int K){
    if(begin == end)
        return v[begin];
    int mid = partition(v,begin,end);
    int num = mid - begin + 1;
    if(num == K ){
        return v[begin + K];
    }
    if( num > K){
        return getKmaxbyQuicksort(v,begin,mid-1,K);
    }
    if( num < K){
            return getKmaxbyQuicksort(v,mid+1,end,K-num);
    }
}
时间: 2024-10-15 12:49:58

获取第K大的数的相关文章

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

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

51 nod 1105 第K大的数

1105 第K大的数 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 数组A和数组B,里面都有n个整数.数组C共有n^2个整数,分别是A[0] * B[0],A[0] * B[1] ......A[1] * B[0],A[1] * B[1]......A[n - 1] * B[n - 1](数组A同数组B的组合).求数组C中第K大的数. 例如:A:1 2 3,B:2 3 4.A与B组合成的C包括2 3 4 4 6 8 6 9 12共9个数. I

统计前k大的数x

我终于敲上了题目--记起来啦! 描述 给定一个数组,统计前k大的数并且把这k个数从大到小输出. 输入 第一行包含一个整数n,表示数组的大小.n < 100000. 第二行包含n个整数,表示数组的元素,整数之间以一个空格分开.每个整数的绝对值不超过100000000. 第三行包含一个整数k.k < n. 输出 从大到小输出前k大的数,每个数一行. 样例输入 10 4 5 6 9 8 7 1 2 3 0 5 样例输出 9 8 7 6 5 //AC自动机x #include<iostream&

找出整数中第k大的数

一  问题描述: 找出m个整数中第k(0<k<m+1)大的整数. 二  举例: 假设有12个整数:data[1, 4, -1, -4, 9, 8, 0, 3, -8, 11, 2, -9],请找出第5大的数(容易知道是0). 三   算法思路:        一种基于快排思想的算法可以在O(n)复杂度内找到第k大的数,首先要知道partition这个函数,它可以调整一个序列 使小于key的元素都排在key左边,大于key的元素都排在key右边,key可以在这个序列中任意选择,一般选择给定序 列

51nod p1175 区间中第K大的数

1175 区间中第K大的数 基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 一个长度为N的整数序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,第K大的数是多少. 例如: 1 7 6 3 1.i = 1, j = 3,k = 2,对应的数为7 6 3,第2大的数为6. Input 第1行:1个数N,表示序列的长度.(2 <= N <= 50000) 第2 - N + 1行:每行1个数,对应序列中的元素.(0 <= S[i] <

《数据结构与算法分析:C语言描述》读书笔记------练习1.1 求第K大的数

求一组N个数中的第k个最大者,设k=N/2. 1 import java.util.Random; 2 3 4 public class K_Max { 5 6 /** 7 * @param args 8 */ 9 //求第K大的数,保证K大于等于1,小于等于array.length/2哦 10 public static int TopK(int array[],int K) 11 { 12 int topk[] = new int [K]; 13 for(int i = 0; i<topk.

51nod 1105 第K大的数

基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 数组A和数组B,里面都有n个整数.数组C共有n^2个整数,分别是A[0] * B[0],A[0] * B[1] ......A[1] * B[0],A[1] * B[1]......A[n - 1] * B[n - 1](数组A同数组B的组合).求数组C中第K大的数. 例如:A:1 2 3,B:2 3 4.A与B组合成的C包括2 3 4 4 6 8 6 9 12共9个数. Input 第1行:2个数N和K,中间用

poj 2401 划分树 求区间第k大的数

题目:http://poj.org/problem?id=2104 划分树待我好好理解下再写个教程吧,觉得网上的内容一般,,, 模板题: 贴代码: #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define CLR(a) memset(a,0,sizeof(a)) const int MAXN = 1000

hdu 4006 第K大的数(优先队列)

N次操作 I是插入一个数 Q是输出第K大的数 Sample Input8 3 //n kI 1I 2I 3QI 5QI 4Q Sample Output123 1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 # include <string> 6 # include <cmath> 7 # incl