分治法求第K小元素(js实现)

145 阅读1分钟

问题:对于给定的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);
    }
}