获取第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);
    }
}

 

posted @ 2015-08-05 16:14  朽木可雕否  阅读(323)  评论(0编辑  收藏  举报