查找第K大的数据
来源:互联网 发布:软件企业质量体系认证 编辑:程序博客网 时间:2024/05/01 07:18
// 查找第K大的数据
// 平均复杂度 O(N)
// 最坏复杂度 O(N*N)
// 参考:
// BFPRT(median-of-medians algorithm)
// http://en.wikipedia.org/wiki/Selection_algorithm
// VC2008
#include "stdafx.h"
#include <algorithm>
#include <iostream>
// 查找参考值在数据中的位置
// iLeft: 数组的起始偏移量
// iRight: 数组的结束偏移量, 总数据量是 (iRight-iLeft+1)
// pivotIndex: 参考值位置
// 返回值:
// 参考值在数组总的位置
// 该位置之前的值都小于参考值, 该位置之后都大于等参考值
template<typename T>
int partition(T iData[], int iLeft, int iRight, int pivotIndex)
{
// 取出参考数据,并将这个数据保存在最后
T pivotValue = iData[pivotIndex];
std::swap(iData[pivotIndex], iData[iRight]);
// 准备存放小于参考值的位置
int storeIndex = iLeft;
// 遍历所有数据(除了保存于最后的参考数据)
for(int i=iLeft; i<iRight; ++i)
{
// 将小于参考值的数据挪到前面
if(iData[i]<pivotValue)
{
// 注意如果i等于storeIndex, 可以考虑优化掉swap
std::swap(iData[storeIndex], iData[i]);
++storeIndex;
}
}
// 将参考值存放在分割位置
std::swap(iData[iRight], iData[storeIndex]);
// 至此, 分割位置为参考值, 位置之前全部都是小于参考值的, 此后都是大于(等于)参考值的
// 返回分割位置
return storeIndex;
}
//
template<typename T>
void quickfindFirstK(T iData[], int iLeft, int iRight, int k)
{
if(iLeft < iRight)
{
// 任意取一个作为参考值
// 这里取位置k的数据
int pivotIndex = k;
// 查找参考数据在数组中的位置
int pivotNewIndex = partition(iData, iLeft, iRight, pivotIndex);
if(pivotNewIndex > k)
{
// 如果选中的参考数据在要确定的位置之后
// 则在后面数据中查找
quickfindFirstK(iData, iLeft, pivotNewIndex-1, k);
}
if(pivotNewIndex < k)
{
// 如果选中的参考数据在要确定的位置之前
// 则在前面数据中查找
quickfindFirstK(iData, pivotNewIndex+1, iRight, k);
}
// 如果参考数据正好在要确定的位置
// 则该数据已经放到位置k, 且之前的数据都不大于这个值, 之后的数据都不小于这个值
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int iData[] = {20,1,19,2,18,3,17,4,16,5,15,6,14,7,13,8,12,9,11,10};
int nCount= sizeof(iData)/sizeof(iData[0]);
quickfindFirstK(iData, 0, nCount-1, nCount/2);
std::cout << "iData[" << nCount/2 << "] = " << iData[nCount/2] << std::endl;
for(int i=0; i<nCount; ++i)
{
std::cout << iData[i] << " ";
}
std::cout << std::endl;
return 0;
}
// 运行结果:
// iData[10] = 11
// 1 2 3 4 5 6 7 8 10 9 11 12 13 14 15 19 17 20 16 18
- 查找第K大的数据
- 查找--第K大的元素
- 查找第k大的数
- 查找第K大的元素
- 查找第 k 大的元素
- 在一堆数据中查找到第k个大的值
- 一堆数据中查找到第k个大的值。
- 查找第K大元素
- 查找数组中第K大的数
- 查找N个数中第K大的数
- 查找数组中第K大的值
- 算法之查找第k大的元素
- 查找给定区间内第K大/小的数
- 查找N个数中第K大的数
- 查找给定区间内第K大的元素
- POJ 3579 Median (查找第k大的值)
- 算法学习 - 查找第K大的数字
- O(n)查找第k小(大)的数
- DirectX函数学习:矩阵函数
- UpdateData()用法以及编辑框的基本操作
- 创建String对象时, 使用String s=new String ("abc")和String s="abc"语句有什么区别?
- 内部用Drupal/PHP开发规范1.2
- select 最常用到的一些查询写法
- 查找第K大的数据
- MQ 队列管理器间消息通讯的方法
- SET协议
- 全局热键的一些知识
- Ubuntu——用VSFTP搭建FTP服务器(2)
- UBUNTU 上网设置
- struts 拦截器
- 我也开博了~~~
- android Service Activity三种交互方式(付源码)