1. Partition方法
在数据中选取分割元素pivot,最终将数据分割成三部分:
data[0....pivotIndex-1] 该部分数据小于pivot
data[pivotIndex] 该数据等于pivot
data[pivotIndex+1... len-1] 该部分数据大于等于pivot
详细分区方法,可以看:快速排序http://my.oschina.net/myspaceNUAA/blog/56776
2.Top(K)提取过程:
1. 对data[p......q]进行分区,根据选取的pivot值分为三个部分
2. 检查分区右侧较大数据:
2.1 data[pivotIndex......q]元素的数量等于K,那么这些元素就是我们要找的TopK数据
2.2 findedCount = q - pivotIndex + 1小于K,说明已经找到Top(findedCount),只需要对
data[p......pivotIndex-1]找 Top(leftCount)即可 (leftCount = K - findedCount)
2.3 q - pivotIndex + 1 大于K, 说明需要缩小搜索范围,从data[pivotIndex + 1......q]中进行Top(K)
3. 伪代码
/*****************************************************
*功能:采用递归算法,计算数组中的TopK数据
*输入:数组data[p...q], K
*输出:result 存放data数组中的TopK数据
******************************************************/
void TopK(int* data, int p, int q, int k)
{
int pivIndex = partition(data, p, q);
if (q-pivIndex == 1) //递归出口
{
if (data[pivIndex] > data[q])
result<---data[pivIndex];
else
result<---data[q];
return;
}
if (q - pivIndex + 1> k) //对应2.3
TopK(data, pivIndex + 1, q, k);
if (q - pivIndex + 1 == k) //对应2.1
result<---data[pivIndex...q];
if (q - pivIndex + 1 < k) //对应2.2
{
//已经找到len - pivIndex + 1个大数据
int findedCount = q - pivIndex + 1;
int leftCount = k - findedCount;
result<---data[pivIndex...q];
TopK(data, p, pivIndex-1, leftCount);
}
}