选第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小元素:分治策略的主要内容,如果未能解决你的问题,请参考以下文章