quickSort 快速排序

本文详细介绍了快速排序算法的基本思想和实现步骤,包括如何选取基准值、分区操作的具体流程,并通过示例展示了整个排序过程。此外,还探讨了算法的时间复杂度问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

快排的基本思想:

选定一个基准值,把所有小于基准值的元素移动到基准值前面,大于基准值的元素移动到基准值后面。我们把这个过程称为“分区”, 分区完成后,基准值在数组的位置就不需要改变了,对分好的两个区域继续进行“分区”,直到分区大小为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 )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值