十大排序算法之快速排序

115 阅读2分钟

1111.webp Quick Sort,又称分区交换排序(partition-exchange sort),最早由东尼·霍尔提出。

快速排序使用分治法(Divide and conquer)策略来把一个序列分为较小和较大的2个子序列,然后递归地排序两个子序列。(分而治之)

快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。

算法步骤

  1. 从数列中挑出一个元素,称为 "基准"(pivot);
  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

image.png

image.png

复杂度

标题数据
平均时间复杂度O(nlogn)
最好情况O(nlogn)
最坏情况O(n²)
空间复杂度O(nlogn)
排序方式In-place
稳定性不稳定

代码演示

    function quickSort(list) {
    function Sort(list, start, end) {
        //数组长度小于一,退出循环
        if (end - start < 1) return;
        //获取到基准的下标,数组分开继续处理
        let mid = partition(list, start, end);
        //比基准小的进行排序,重复找基准-》排序
        Sort(list, start, mid - 1);
        //比基准大的进行排序,重复找基准-》排序
        Sort(list, mid + 1, end);
        return list
    }
    Sort(list, 0, list.length - 1)
    return list
}

function partition(list, start, end) {
    //设置数组最后一位为基准值
    let pivot = list[end],
        index = start;
    for (let i = start; i <= end; i++) {
        //当前的值比基准小,放在左边,交换位置
        if (list[i] <= pivot) {
            //此时进行交换,比基准小的在左边,大的在右边
            [list[i], list[index]] = [list[index], list[i]];
            index++
        }
    }
    //最后一次比较相当于自己和自己比较(end和pivot),所以要减1,得到基准的位置
    return index - 1
}

image.png