数据结构与算法:快速排序

一、原理

对于任意一个无序数组,我们随机的选一个元素作为基准元素(例如:数组中的最后一个或者第一个元素, 然后我们将数组中的剩余元素分别与基准元素进行比较,将小于或等于基准元素的数据放在基准元素的左边,将大于基准元素的数据放在基准元素的右边,当全部比较完成之后,基准元素在数组中的位置就确定了下来。然后,在分别对左边数组和右边的数组递归的进行上面的操作,直到每一个元素的位置都唯一确定下来。

注意1:快速排序最难理解的地方是如何将小于基准元素的元素放在左边,将大于基准元素的元素放在右边,本示例代码使用双指针方法
注意2:若要想得到增序排序,即排序后数据从小到大排列,则将最右侧数据作为基准元素,从左向右遍历元素并与基准元素比较,这样才能将小于基准元素的数据全都放在左侧,大于基准元素的数据全都放在右侧;若想得到降序排序,即排序后数据从大到小排序,则与上述操作相反就行,即 将最左侧数据作为基准元素,从右往左遍历元素并与基准元素比较,这样就能将小于基准元素的数据放在最右侧,大于基准元素的数据放在最左侧,这样便是倒序排序。

二、示例代码

1、增序排序

public class QuickSort {
    /**
     * 获取
     *
     * @param nums
     * @param mark  基准元素
     * @param start 数组开始下标位置
     * @param end   数组结束下标位置
     * @return 基准元素最终下标位置
     */
    public static int getPartIndex(int[] nums, int mark, int start, int end) {
        int j = start;
        for (int i = start; i <= end; i++) {
            if (nums[i] <= mark) {
                swap(nums, i, j);
                j++;
            }
        }

        return j - 1;
    }

    /**
     * 交换相应位置数据
     *
     * @param nums
     * @param i
     * @param j
     */
    public static void swap(int[] nums, int i, int j) {
        int swap = nums[i];
        nums[i] = nums[j];
        nums[j] = swap;
    }

    /**
     * 递归对不同partition排序
     *
     * @param nums
     * @param mark 基准元素
     * @param start
     * @param end
     */
    public static void partRecursion(int[] nums, int mark, int start, int end) {
        //递归结束条件
        if (start == end)
            return;
        int partIndex = getPartIndex(nums, mark, start, end);
        if (partIndex == start) {
            partRecursion(nums, nums[end], partIndex + 1, end);
        } else if (partIndex == end) {
            partRecursion(nums, nums[partIndex - 1], start, partIndex - 1);
        } else {
            partRecursion(nums, nums[partIndex - 1], start, partIndex - 1);
            partRecursion(nums, nums[end], partIndex + 1, end);
        }
    }

    public static void main(String[] args) {
        int[] nums = {5, 1, 1, 2, 0, 0, 9, 6};
        int end = nums.length - 1;
        partRecursion(nums, nums[end], 0, end);
        String outStr = "";
        for (int i : nums) {
            outStr = outStr + "," + String.valueOf(i);
        }
        System.out.println(outStr);
    }
}
0 0 1 1 2 5 6 9

2、降序排序

public class JavaTest1 {
    public static void main(String[] args) {
        int[] nums = {8, 2, 1, 7, 3, 5, 9, 6};
        int length = nums.length;
        quickSort(nums, nums[0], 0, length - 1);
        for (int i = 0; i < length; i++) {
            System.out.println(nums[i]);
        }
    }

    /**
     * @param nums  待排序数组
     * @param mark  基准元素
     * @param left  最左侧index
     * @param right 最右侧index
     */
    private static void quickSort(int[] nums, int mark, int left, int right) {
        if (left == right)
            return;
        int partition = getPartition(nums, mark, left, right);
        if (partition == left) {
            quickSort(nums, nums[left], left + 1, right);
        } else if (partition == right) {
            quickSort(nums, nums[left], left, right - 1);
        } else {
            //对基准元素左侧数组排序
            quickSort(nums, nums[left], left, partition - 1);
            //对基准元素右侧数组排序
            quickSort(nums, nums[partition + 1], partition + 1, right);
        }
    }

    private static int getPartition(int[] nums, int mark, int left, int right) {
        int i = right;//用于遍历数组
        int j = right;//用于标记替换位置

        for (; i >= left; i--) {
            if (nums[i] <= mark) {
                swap(nums, i, j);
                j--;
            }
        }

        return j + 1;
    }

    private static void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}
9
8
7
6
5
3
2
1

三、参考文章

快速排序算法–Java实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值