线性时间查找第k大元素
2013-08-02 19:42
162 查看
/* 找出第k大的元素可以使用:堆排序,桶排序等方法,这里介绍一种O(n)的分治算法:先对数组划分,然后判断第k小的元素应该在哪个分组,再对相应的分组递归 */
int partion(int *a, int start, int end) {
int rnd = start + rand() % (end - start + 1);
int tmp = a[rnd];
a[rnd] = a[start]; //随机获取参考值
while (start < end) {
for (; start < end && a[end] > tmp; end--);
if (start < end) {
a[start++] = a[end];
}//从右边选取第一个小于tmp的值复制到a[start]
for (; start < end && a[start] < tmp; start++);
if (start < end) {
a[end--] = a[start];
}//从左边选取第一个大于tmp的值复制到a[end]
}
a[start] = tmp; //将保存在tmp里面的a[start]存到最终的位置
return start;
}
/* n为数组的个数,要找出第k大的值,k从1开始计数 */
int findk(int *a, int start, int end, int k) {
assert(k > 0 && k <= end - start + 1);
int tmp = partion(a, start, end); //随机拆分成左小右大的2部分
int nlower = tmp - start + 1; //左边小元素的个数
if (k == nlower) { //若左边小元素个数恰好为k,则返回
return a[tmp];
} else if (nlower < k) { //左边元素个数比k少,则在右边继续寻找剩下的k-nlower
return findk(a, tmp + 1, end, k - nlower);
} else {
return findk(a, start, tmp - 1, k);//继续在左边部分寻找第k大
}
}
int partion(int *a, int start, int end) {
int rnd = start + rand() % (end - start + 1);
int tmp = a[rnd];
a[rnd] = a[start]; //随机获取参考值
while (start < end) {
for (; start < end && a[end] > tmp; end--);
if (start < end) {
a[start++] = a[end];
}//从右边选取第一个小于tmp的值复制到a[start]
for (; start < end && a[start] < tmp; start++);
if (start < end) {
a[end--] = a[start];
}//从左边选取第一个大于tmp的值复制到a[end]
}
a[start] = tmp; //将保存在tmp里面的a[start]存到最终的位置
return start;
}
/* n为数组的个数,要找出第k大的值,k从1开始计数 */
int findk(int *a, int start, int end, int k) {
assert(k > 0 && k <= end - start + 1);
int tmp = partion(a, start, end); //随机拆分成左小右大的2部分
int nlower = tmp - start + 1; //左边小元素的个数
if (k == nlower) { //若左边小元素个数恰好为k,则返回
return a[tmp];
} else if (nlower < k) { //左边元素个数比k少,则在右边继续寻找剩下的k-nlower
return findk(a, tmp + 1, end, k - nlower);
} else {
return findk(a, start, tmp - 1, k);//继续在左边部分寻找第k大
}
}
相关文章推荐
- 在线性时间复杂度内求解第k小元素问题
- 分治算法;随机化划分函数;快速排序;线性时间选择第K小元素;快速排序平均时间复杂度nlgn;
- 线性时间查找固定频率的元素
- 线性时间选择第K小元素(随机化选择第K小元素)C++
- java线性时间寻找第k小元素
- 算法导论学习之线性时间求第k小元素+堆思想求前k大元素
- 线性时间内查找第K小(大)算法
- 选择问题:线性时间内找到序列的第k小的元素
- 线性时间选择:从n个元素中找出第k小的元素
- 最坏为线性时间的查找第i小元素
- 面试算法:lg(k)时间查找两个排序数组合并后第k小的元素
- 算法导论学习之线性时间求第k小元素+堆思想求前k大元素
- 在数组A中寻找第k小的元素-最坏情况为线性时间的算法
- 数组中查找第k小元素的复杂度为O(n)的算法
- 线性的时间内选择出rank n的元素
- 查找数组第k大的元素
- 线性时间内从一个数组中找出第K个最小的元素
- 主元素问题的线性时间算法
- 查找数组中第k小的元素
- 第九章中位数和顺序统计学 之 “寻找第i小元素之最坏情况线性时间的选择 最坏运行时间就为O(n)算法”