标签搜索

目 录CONTENT

文章目录

【算法模板】快速排序

陈铭
2022-04-18 / 0 评论 / 0 点赞 / 203 阅读 / 430 字 / 正在检测是否收录...

例题:排序数组

力扣912题为例:

给你一个整数数组 nums,请你将该数组升序排列。

快速排序法

class Solution {
    public int[] sortArray(int[] nums) {
        randomizedQuicksort(nums, 0, nums.length - 1);
        return nums;
    }

    public void randomizedQuicksort(int[] nums, int l, int r) {
        if (l < r) {
			// 随机选择主元,即划分数组为两份的中间位置
            int pos = randomizedPartition(nums, l, r);
			// 左边排序
            randomizedQuicksort(nums, l, pos - 1);
			// 右边排序
            randomizedQuicksort(nums, pos + 1, r);
        }
    }

    public int randomizedPartition(int[] nums, int l, int r) {
		// 套路1:随机选一个作为我们的主元,并右置
        int i = new Random().nextInt(r - l + 1) + l;
        swap(nums, r, i);
		// 计算主元
        return partition(nums, l, r);
    }

    public int partition(int[] nums, int l, int r) {
        int pivot = nums[r];
		// 套路2:维护两个指针(快慢指针)
		// 初始时指针分别为-1和0
		// 慢指针为i,总是指向小于主元的最后位置
		// 快指针为j,总是指向大于主元的最后位置
        int i = l - 1;
        for (int j = l; j <= r - 1; ++j) {
            if (nums[j] <= pivot) {
				// 当小于主元的情况时,有两种情况
				// (1)i==j,swap都不改变
				// (2)i<j,swap交换i+1和j的元素,此时i+1就时大于主元的第一个位置(慢指针为i,总是指向小于主元的最后位置)
                i = i + 1;
                swap(nums, i, j);
            }
        }
		// 把右置的主元返回中间,即与大于主元的第一个位置的元素交换
		// 这样以主元为界,左右区域总是小于/大于主元
        swap(nums, i + 1, r);
		// 返回主元位置
        return i + 1;
    }

    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}
0

评论区