漫谈排序算法——快速排序

154 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情

前言

今天我们要来聊一聊最为经典的算法——快速排序(Quicksort),快速排序有点跟我们之前讲到的归并排序有点相似,但是解决的思路是有所不同的。

快速排序算法原理

快速排序的主体思想是这样的:我们需要对一个数组中的下标p到r之间的一组数据的话,我们选择p到r之间的任意一个数据作为pivot(分区点)。然后遍历p到r之间的数据,将小于pivot的数放到左边,将大于pivot的数据放到右边。将pivot放到中间。经过这个流程后,p到r之间的数据就被划分成三个部分,p到q-1小于pivot,中间是pivot。随后的q+1到r之间的都是大于pivot的。因为快速排序也是基于分治和递归的处理思想的。只要我们分区分到区间长度只有1的时候,那么就代表区间都是有序的了。也就是排序完成了。由此可以得到我们的递归公式是如下所示的:

quick_sort(p…r) = quick_sort(p…q-1) + quick_sort(q+1, r)

p >= r

由递归公式的话,我们可以得到对应的代码实现

public void quickSort(int arr[], int begin, int end) {
    if (begin < end) {
        int partitionIndex = partition(arr, begin, end);

        quickSort(arr, begin, partitionIndex-1);
        quickSort(arr, partitionIndex+1, end);
    }
}

private int partition(int arr[], int begin, int end) {
    int pivot = arr[end];
    int i = (begin-1);

    for (int j = begin; j < end; j++) {
        if (arr[j] <= pivot) {
            i++;

            int swapTemp = arr[i];
            arr[i] = arr[j];
            arr[j] = swapTemp;
        }
    }

    int swapTemp = arr[i+1];
    arr[i+1] = arr[end];
    arr[end] = swapTemp;

    return i+1;
}

如果我们不考虑内存消耗的话,可以额外的采用两个左右数组来进行分区的,但是这样快速排序就不是原地算法了,它所具备的优势就不存在了。所以采用原地分区的算法的快速排序性能才会更好

总结

快速排序是非常经典的算法之一,值得我们去好好学习掌握的。