1.问题
在数组中,选取第k个小的元素,采用特定分治策略。
2.解析
3.设计
int select(int a[], int l, int r, int k)
{
int group, i, left, right, mid;
int pivot, p, lnum;
//规模小直接排序返回
if (r - l + 1 <= 5)
{
insertsort(a, l, r);
return a[l + k - 1];
}
//分组规模
group = (r - l + 1 + 5) / 5;
//遍历分组之后对中位数排序
for (i = 0; i < group; ++i)
{
left = l + 5 * i;
right = (l + 5 * i + 4) > r ? r : l + 5 * i + 4;
mid = (left + right) / 2;
insertsort(a, left, right);
swap(a[l + i], a[mid]);
}
// 测试
// for(i=1;i<=r-l+1;i++) cout<<a[i]<<" ";
// cout<<endl;
// cout<<l+group-1<<" "<<(group+1)/2<<" "<<group<<endl;
pivot = select(a, l, l + group - 1, (group + 1) / 2);
p = partition(a, l, r, pivot);
// cout<<pivot<<" "<<p<<endl;
if (p-l+1 == k)
return a[p];
//判断在左区间还是在右区间
else if (k <= p-l)
return select(a, l, p - 1, k);
else
return select(a, p + 1, r, k-(p-l)-1);
}
4.分析
5.源码
https://github.com/Chenzh0205/Algorithm/tree/main/%E4%BD%9C%E4%B8%9A6