- 分析
利用快速排序的partition函数,每次能够定位到最小的index个元素,当index == k-1时便得到了最小的k个元素。
using namespace std;
int randomInRange(int start, int end) {
return rand() % (end - start + 1) + start;
}
void swap(int& n1, int& n2) {
int tmp = n1;
n1 = n2;
n2 = tmp;
}
int partition(int* numbers, int length, int start, int end) {
if(numbers == NULL || length <= 0 || start < 0 || end >= length)
return -1;
int index = randomInRange(start, end);
swap(numbers[index], numbers[end]);
int cursor = start - 1;
// cursor 指向当前扫过(或交换过后)的最近一个小于number[end]的元素
// 未交换前,cursor的下一个元素是比number[end]大的元素
for(index = start; index < end; index++) {
if(numbers[index] < numbers[end]) {
++cursor;
if(cursor != index) {
swap(numbers[cursor], numbers[index]);
}
}
}
++cursor;
swap(numbers[cursor], numbers[end]);
// 返回的cursor指向的numbers[cursor]是这轮partition后数组中的第cursor大的元素
return cursor;
}
void GetLeastKNumbers(int* input, int length, int* output, int k) {
if(input == NULL || length <= 0 || output == NULL
|| k <= 0 || k > length)
return;
int start = 0;
int end = length - 1;
int index = partition(input, length, start, end);
while(index != k - 1) {
if(index > k - 1) {
end = index - 1;
index = partition(input, length, start, end);
} else {
start = index + 1;
index = partition(input, length, start, end);
}
}
for(int i = 0; i < k; ++i)
output[i] = input[i];
}
int main() {
int length = 9;
int* numbers = new int[9];
for(int i = 0; i < length; ++i) {
if(i % 2 == 0)
numbers[i] = i + 2*i;
else {
numbers[i] = numbers[i-1] % i;
}
cout << numbers[i] << " ";
}
cout << endl;
int k = 4;
int* output = new int[k];
GetLeastKNumbers(numbers, length, output, k);
for(int i = 0; i < k; ++i)
cout << output[i] << " ";
}