按编程之美上解法二的所述,类似快速排序的划分方法,N个数存储在数组S中,再从数组中随机选取一个数X,把数组划分为Sa和Sb俩部分,Sa<=X<=Sb,如果要查找的k个元素小于Sa的元素个数,则返回Sa中较小的k个元素,否则返回Sa中所有的元素+Sb中较小的k-|Sa|个元素。不断递归下去,把问题分解成更小的问题,平均时间复杂度为O(N)
// Copyright 2012 Jike Inc. All Rights Reserved.
// Author: jichenghui@jike.com(Chenghui Ji)
// Date : 2012-08-24 16:35:51
// Brief :
#include <iostream>
using namespace std;
int partition(int* data, int left, int right) {
if (left > right) {
return -1;
} else {
int polit = data[left];
while(left < right) {
while(right > left && data[right] >= polit)
right--;
data[left] = data[right];
while (left < right && data[left] <= polit)
left++;
data[right] = data[left];
}
data[left] = polit;
}
return left;
}
void topk_qsort(int* data, int left, int right, int k) {
if (left >= right || k > right - left + 1) {
return;
}
int polit = partition(data, left, right);
if (polit < left || polit >= right) return;
int left_len = polit - left + 1;
if (left_len == k) return;
else if (left_len > k) {
topk_qsort(data, left, polit-1, k);
} else {
topk_qsort(data, polit + 1, right, k - left_len);
}
}
int main() {
int data[] = {13,2,3,5,67,8,9,10,17,6};
int len = sizeof(data)/sizeof(data[0]);
cout << "orignal data:" << endl;
for (int i = 0; i < len; ++i) {
cout << data[i] << " ";
}
cout << endl;
int k = 3;
cout << "top" << k << "data:" << endl;
topk_qsort(data, 0, len-1, k);
for (int i = 0; i < len; ++i) {
cout << data[i] << " ";
}
cout << endl;
return 0;
}