查找第K大的数据
2011-03-14 11:03
211 查看
// 查找第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
// 平均复杂度 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
相关文章推荐
- C语言-数据结构-双链表插入查找
- 数据结构实验之查找五:平方之哈希表
- 查找数据库指定数据的数据表和字段名称SQL语句
- 查找数组内重复数字(长度为n,里面的数据的值在0-n-1之间)
- mysql模糊查找:一个表T2的某列数据,作为另一个表T1查找条件进行模糊查找
- 3374 数据结构实验之查找二:平衡二叉树
- POJ_3685_Matrix_(二分,查找第k大的值)
- Excel数据分析与业务建模_第二章_查找函数VLOOKUP及HLOOKUP(语法及应用实例)
- 在O(n)时间内查找数组内第k小的数
- 数据结构上机实验之二分查找之平衡二叉树
- mysql 数据表中查找、删除重复记录
- 数据结构之查找(五)——二叉查找树
- 算法设计--查找无序数组中第K大的数字
- 易大漠内存入门之数据查找与使用(…
- SDUT 2040 数据结构上机实验之顺序查找
- 查找第K小的元素
- B树查找,磁盘查找数据
- 数据结构之三大查找(续)
- 数据结构实验之查找六:顺序查找
- SDUT 3373 数据结构实验之查找一:二叉排序树