排序

  1. 快速排序
    1. 递归版

一直学,一直忘。希望这此能记牢。。

快速排序

递归版

分两个函数。

一个函数用来进行分区。

当递归到区间只有一个元素时,就可以视作排序完成而返回了。此时 p 两边的数组区间就排好序了。

另一个函数被递归调用,以对分区进行排序。

分区函数中,哨兵元素可以随机取 [l,r] 内的值。取区间最右的值比较方便。
可以理解为分为四个区间:

上图中,[left, i) 为小于哨兵的元素,图中为蓝色区间。[i,j} 为大于哨兵的元素,红色区间。[j,r) 为待比较元素,灰色区间。哨兵自己构成一个区间。

  • 当前比较的元素小于哨兵时,交换当前比较的元素与 i 指向的元素,并且 ij,都加 1。
  • 当前比较的元素大于哨兵时,只需 j 加 1 即可。

JavaScript 完整代码:

function quickSort(arr, l, r) {
    if (r <= l) {
        return
    }
    let q = partition(arr, l, r);
    console.log(q);
    quickSort(arr, l, q - 1);
    quickSort(arr, q + 1, r);
}

function partition(arr, l, r) {
    let p = r;  // 可以随机选取 [l,r] 内的值, 这里选取最右作为哨兵索引
    // 将哨兵放到最右边, 便于排序.
    // 由于这里选取的是 r, 所以不用交换了
    // [arr[p], arr[r]] = [arr[r], arr[p]];
    let i = l;
    for (let j = l; j <= r - 1;) {
        if (arr[j] <= arr[r]) {
            [arr[i], arr[j]] = [arr[j], arr[i]];
            i += 1;
        } 
        j += 1;
    }
    // 交换哨兵和比哨兵大的元素, 此时哨兵的位置就是最终位置了
    [arr[i], arr[r]] = [arr[r], arr[i]];
    return i;
}

递归版的参考视频,图片来源:
五点七边


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论。
我的空间