码迷,mamicode.com
首页 > 其他好文 > 详细

选第k小元素:分治策略

时间:2020-03-31 18:59:54      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:中位数   back   dex   分治   ret   for   情况下   插入排序   复杂   

解析:

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小元素:分治策略

标签:中位数   back   dex   分治   ret   for   情况下   插入排序   复杂   

原文地址:https://www.cnblogs.com/zhhhb/p/12607421.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!