问题:对于给定的n个数S,从中找到第k小的元素
分析:采用分治法进行霍尔划分
以S中的某个数m为标准,将S划分为子数组S1,S2,使得m大于等于S1中所有的数,小于等于S2中所有的数,数组S1的个数为|S1|,数组S2的个数为|S2|,对于K(表示第k小)有以下条件:
- K<|S1|,则在S1数组中找第K小元素
- K=|S1|+1,则m就是第K小元素
- K>|S1|+1,则在S2中找第(k-|S1|-1)小元素
js代码
let selectK = (arr, begin, end, k) => {
if (begin >= end) {
return arr[left];
}
let l = begin;
let r = end;
let pivot = arr[begin];
while (l < r) {
while (l < r && arr[r] >= pivot) {
r--;
}
while (l < r && arr[l] <= pivot) {
l++;
}
[arr[l], arr[r]] = [arr[r], arr[l]];
}
[arr[begin], arr[l]] = [arr[l], arr[begin]];
//pivot左右刚好有k-1个元素,则pivot为第k小元素
if (r - begin + 1 == k) {
return pivot;
}
//如果第k小元素在pivot右边,则在右边找k-(j+left-1)小元素
if (r - begin + 1 < k) {
return selectK(arr, r + 1, end, k - r + begin - 1);
} else {
return selectK(arr, begin, r - 1, k);
}
}