图文并茂!一文教你掌握十大排序算法之快速排序

目录

1. 快速排序原理介绍

2. 快速排序算法步骤

3. 代码实现

1. 快速排序原理介绍

快速排序是一种不稳定的排序算法,它的时间复杂度是O(N*logN),快速排序的基本思想是:每次从待排序的序列中选出一个基准数/枢轴(英文称为pivot),然后比它小的数都放到它的左边,比它大的数都放到它的右边,然后再对pivot的左边和右边两个序列进行快速排序,当排序的序列中只有一个数时不需要进行排序,此时排序已经完成。这里也有用到一种“分治思想”

举个例子:假设现在有一个序列:[33, 27, 41, 26, 78, 19, 52, 81],首先取第一个元素作为枢轴:pivot = 33,对整个序列进行快速排序,排序后的结果为:[19, 27, 26, 33, 78, 41, 52, 81],可以看到以33为pivot的第一轮排序后,比它小的元素全部位于33的左边,比它大的元素全部位于33的右边,此时我们再对左右两边的序列:[19, 27, 26]和[78, 41, 52, 81]进行快速排序(分治),同样取每个序列的第一个元素作为枢轴······直至序列只有一个元素时,此时整个序列已经有序。

因为快速排序的效率非常高,而且掌握它也有一定的难度,所以各大企业都会拿这个来考察程序员,通常上来就让你写一个快速排序给他过目,掌握这个排序真的已经是企业的基础了,也是考察一个程序员基础的重要指标之一了。

2. 快速排序算法步骤

现在有一个待排序的序列:[33, 27, 41, 26, 78, 19, 52, 81],使用快速排序算法进行排序,我会以第一轮排序为例演示快速排序的整个流程。

我假定每次排序都取第一个数为基准数(pivot),则第一轮排序pivot = 33,由于33被pivot这个变量存储,所以我们可以认为index = 0的位置是挖空出来的,可以放数据进去,也就是下图中的红色区域。然后使用两个指针left和right分别指向序列的首部和尾部。初始化left = 0,right = 7

【下图中的前三行】(1)从后往前扫描元素,找到第一个小于pivot的元素,找到下标right = 5的元素满足条件(19 < 33),插入到当前的空闲位置(left = 0),则arr[left] = arr[right] 即 arr[0] = arr[5] = 19,而此时空闲位置由 left = 0 转化为 right = 5。将左指针left++(left = 1)

【下图中的第四五行】(2)从前往后扫描元素,找到第一个大于pivot的元素, 找到下标left = 2的元素满足条件(41 > 33)插入到当前的空闲位置(right = 5),则arr[right] = arr[left] 即 arr[5] = arr[2] = 41,空闲位置由right = 5转化为left = 2。将右指针right--(right = 4)

【下图中的第六行】(3)从后往前扫描元素,找到下标right = 3的元素满足条件(26 < 33),插入到当前空闲位置(left = 2),则arr[left] = arr[right] 即 arr[2] = arr[3] = 26,空闲位置由left = 2转化为right = 3。将指针left++(left = 3)

下图中的第七行(4)从前往后扫描元素,此时 left = right,代表所有元素都已经与pivot比较过,换言之所有需要交换位置的元素都已经交换完毕,所以最后将pivot填到最后的空闲位置(left = right = 3)即arr[left]/arr[right] = pivot 即 arr[3] = 33,此时第一轮排序完成,进行下一轮的快速排序(重复这四个步骤)

3. 代码实现

/**
 * @author Zeng
 * @date 2020/3/2 9:09
 */
public class QuickSort {

    public static void main(String[] args) {
        int[] arr = new int[]{33, 27, 41, 26, 78, 19, 52, 81};
        quickSort(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }

    public static void quickSort(int[] arr, int begin, int end) {
        if (begin < end) {
            //以第一个数作为基准数
            int pivot = arr[begin];
            //左指针,找到比基准数大的元素
            int left = begin;
            //右指针,找到比基准数小的元素
            int right = end;
            while (left < right) {
                //从后往前找到第一个比pivot小的元素
                while (left < right && arr[right] >= pivot) {
                    right--;
                }
                //将元素填到空闲位置
                if (left < right) {
                    arr[left] = arr[right];
                    left++;
                }
                //从前往后找到第一个比pivot大的元素
                while (left < right && arr[left] < pivot) {
                    left++;
                }
                //将元素填到空闲位置
                if (left < right) {
                    arr[right] = arr[left];
                    right--;
                }
                //回填pivot
                if (left == right) {
                    arr[left] = pivot;
                }
                //对pivot左边的序列进行快速排序
                quickSort(arr, begin, left - 1);
                //对pivot右边的序列进行快速排序
                quickSort(arr, left + 1, end);
            }
        }
    }
}
//[19, 26, 27, 33, 41, 52, 78, 81]
发布了50 篇原创文章 · 获赞 46 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_41949328/article/details/104613688