quickSort 快速排序

快排的基本思想:

选定一个基准值,把所有小于基准值的元素移动到基准值前面,大于基准值的元素移动到基准值后面。我们把这个过程称为“分区”, 分区完成后,基准值在数组的位置就不需要改变了,对分好的两个区域继续进行“分区”,直到分区大小为1。
图片来自wiki
图片来自维基百科

1、对待排序的数组进行划分

下面举例说明划分的流程:

1.1、 首先把数组第0个元素前面的位置(-1)作为“小于区域”,数组最后一个元素作为划分的基准值(暂时让这个基准值位于“大于区域”

1.2、从0开始遍历数组,当前值如果小于基准值,则“小于区域”+ 1, 如果大于基准值,则当前值与“大于区域”的前一个元素交换,“大于区域+ 1”,如果等于基准值则什么都不做,下标加1,如此重复,直至下标与“大于区域”的边界相遇。

1.3 把数组最后一个元素与大于区域的第1个元素交换,便可以得到划分好的三个区域(小于、等于、大于)

1.4返回等于区域的左右边界

这里写图片描述

2、对划分好的“小于区域”与“大于区域”继续执行划分,直至不能再划分,则数组顺序排好了。

package com.yuan.sort;

public class QuickSort {

    public static void main(String[] args) {
        int[] test;
        int maxSize = 20;
        int maxValue = 50;
        test = generateRandomArray(maxSize, maxValue);
        printArray(test);
        quickSort(test);
        printArray(test);
    }

    private static void quickSort(int[] arr) {
       if (arr == null || arr.length < 2)
           return;
       quickSort(arr, 0, arr.length - 1);
    }

    private static void quickSort(int[] arr, int left, int right) {
        if (left < right) {
            swap(arr, left + (int)(Math.random() * (right - left + 1)), right);     //随机快排
            int[] p = partition(arr, left, right);
            quickSort(arr, left, p[0] - 1);
            quickSort(arr, p[1] + 1, right);
        }
    }

    private static int[] partition(int[] arr, int left, int right) {
        int less = left - 1;
        int more = right;
        while (left < more) {
            if (arr[left] < arr[right])
                swap(arr, ++less, left++);
            else if (arr[left] > arr[right])
                swap(arr, --more, left);
            else
                left++;
        }
        swap(arr, left, right);
        return new int[]{less + 1, more};   //返回等于区域的左右边界。
    }

    private static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    private static int[] generateRandomArray(int maxSize, int maxValue) {
        int[] arr = new int[maxSize];//[(int)((maxSize + 1) * Math.random())];
        for (int i = 0; i < maxSize; i++) {
            arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
        }
        return arr;
    }

    private static void printArray(int[] arr) {
        for (int prime : arr) {
            System.out.print(prime + " ");
        }
        System.out.println();
    }
}

测试结果

input: 18 -13 -35 13 -9 -27 16 11 -20 11
output: -35 -27 -20 -13 -9 11 11 13 16 18

算法复杂度

1、当每次划分的区域大小相当的时候,得到最好时间复杂度 O(nlogn) O ( n ⋅ l o g n )
2、当每次划分的区域大小为1与n-1时,得到最坏时间复杂度 O(n2) O ( n 2 )

快速排序QuickSort)是一种高效的排序算法,它基于分治策略。该算法首先选择一个元素作为基准值(pivot),然后将待排序数组按照基准值分成两个子数组,一边是所有小于基准值的元素,另一边是所有大于等于基准值的元素。然后对两个子数组分别递归地进行快速排序,最后将两个子数组合并起来即可得到完整的有序数组。 以下是使用C++实现快速排序的代码: ```cpp void quickSort(vector<int>& nums, int left, int right) { if (left >= right) return; // 递归终止条件 int pivot = nums[left]; // 选择第一个元素作为基准值 int i = left, j = right; while (i < j) { // 一趟快速排序 while (i < j && nums[j] >= pivot) j--; // 从右往左找到第一个小于基准值的元素 if (i < j) nums[i++] = nums[j]; // 将该元素放入左半部分 while (i < j && nums[i] < pivot) i++; // 从左往右找到第一个大于等于基准值的元素 if (i < j) nums[j--] = nums[i]; // 将该元素放入右半部分 } nums[i] = pivot; // 将基准值放入合适的位置 quickSort(nums, left, i - 1); // 递归地对左半部分进行快速排序 quickSort(nums, i + 1, right); // 递归地对右半部分进行快速排序 } ``` 其中,`nums`表示待排序数组,`left`和`right`表示当前子数组的左右边界(初始时应为0和`nums.size()-1`)。我们首先选择第一个元素作为基准值,然后使用双指针i和j在数组中进行一趟快速排序,将小于基准值的元素放入左半部分,将大于等于基准值的元素放入右半部分。最后将基准值放入合适的位置,并递归地对左右两个子数组进行快速排序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值