选第k小元素:分治策略

Posted zhhhb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了选第k小元素:分治策略相关的知识,希望对你有一定的参考价值。

解析:

1. 将n个元素每5个一组,分成n/5(上界)组。

2. 取出每一组的中位数,任意排序方法,比如插入排序。

3. 递归的调用selection算法查找上一步中所有中位数的中位数,设为x,偶数个中位数的情况下设定为选取中间小的一个。

4. 用x来分割数组,设小于等于x的个数为k,大于x的个数即为n-k。

5. 若i==k,返回x;若i<k,在小于x的元素中递归查找第i小的元素;若i>k,在大于x的元素中递归查找第i-k小的元素。

终止条件:n=1时,返回的即是i小元素。

 

时间复杂度:O(n)

 

代码:

int select_kth_smallest(vector<int> q, size_t k);
int choose_mid(vector<int>& q, int left, int right);
int selection(vector<int> v);
 
int select_kth_smallest(vector<int> q, size_t k){
    int bot = 0, top = q.size();
    while(bot < top){
        int left = bot, right = bot, i;
        int index = choose_mid(q, bot, top);
        while(right < top){
            if(q[right] < index){
                int temp = q[left];
                q[left] = q[right];
                q[right] = temp;
                left++;
            }
            if(q[right] == index)
                i = right;
            right++;
        }
        q[i] = q[left];
        q[left] = index;
        /*
        for(int a=0; a<q.size(); a++)
            cout<< q[a]<< ‘ ‘;
        cout<< endl;
        cout<< index<< endl;
        cout<< bot<< ‘ ‘<< top<< endl;
        cout<< left<< ‘ ‘<< right<< endl; 
        */
        if(left+1 < k)
            bot = left + 1;
        else if(left+1 > k)
            top = left;
        else
            return index;
    }
    return -1;
}
 
int choose_mid(vector<int>& q, int left, int right){
    vector<int> v;
    while(left+5 < right){
        int mid = selection(vector<int>(&q[left], &q[left+5]));
        v.push_back(mid);
        left += 5;
    }
    int mid = selection(vector<int>(&q[left], &q[right]));
    v.push_back(mid);
    
    return selection(v);
}
 
int selection(vector<int> v){
    int size = v.size();
    for(int a=1; a<size; a++){
        int b = a;
        int temp = v[b];
        while(b>0 && temp<v[b-1]){
            v[b] = v[b-1];
            b--;
        }
        v[b] = temp;
    }
    int mid = (size-1)/2;
    
    return v[mid];
}

int main() {
    
    return 0;
} 

 

以上是关于选第k小元素:分治策略的主要内容,如果未能解决你的问题,请参考以下文章

分治策略 - 典型实例 - 选择问题

选择问题(分治策略)

利用分治策略,在n个不同元素中找出第k个最小元素。

(学习6)特殊的分治策略算法——BFPTR

分治策略合并多个排序数组

第二章:递归与分治策略