排序算法-快速排序

快速排序是一种高效的分治算法 ,其核心思想是通过一次**分区(Partition)**操作将序列分为两部分,其中一部分的所有元素均小于另一部分,然后递归地对子序列排序。

快速排序步骤

  1. 选择基准(Pivot):从序列中选取一个元素作为基准(通常选第一个、最后一个或随机元素)。

  2. 分区操作 :将序列重新排列,所有比基准小的元素放在基准左侧,比基准大的放在右侧。

    遍历数组,根据两个条件进行操作:

    a:如果当前元素小于等于基准数时,首先分区指示器右移一位

    b:在a的基础上,如果当前元素下标大于分区指示器下标时,当前元素和分区指示器所指元素交换

  3. 递归排序:对基准左侧和右侧的子序列分别递归调用快速排序。

代码实现

java 复制代码
package Sort;

public class QuickSort {
    public static void main(String[] args) {
        int[] nums = new int[]{3,5,8,1,2,9,4,7,6};
        int[] res = getQuickSort(nums,0,nums.length-1);
        for (int i = 0; i < res.length; i++) {
            System.out.print(res[i]+" ");
        }
    }
    public static int[] getQuickSort(int[] nums,int start,int end){
        if (nums.length < 1 || start < 0 || end >= nums.length || start > end) return null;

        // 数据分割成独立的两个部分时,从哪分区的指示器
        int zoneIndex = partition(nums,start,end);
        // 递归排序左子数组
        if (zoneIndex > start){
            getQuickSort(nums,start,zoneIndex-1);
        }
        // 递归排序右子数组
        if (zoneIndex < end){
            getQuickSort(nums,zoneIndex+1, end);
        }
        return nums;
    }

    private static int partition(int[] nums, int start, int end) {
        //只有一个元素时,无需再分区
        if (start == end) return start;
        //随机选择一个元素作为基准数
        int pivot = (int)(start + Math.random() * (end-start+1));
        //zoneIndex为分区指示器,初始值为区分头元素下标-1
        int zoneIndex = start-1;
        //将基准数和分区尾元素交换位置
        swap(nums,pivot,end);

        //也可直接将尾元素作为基准数,那就不需要设置成随机数并交换尾元素了
//        int pivot = nums[end];

        //遍历数组,根据两个条件进行操作
        //a:如果当前元素小于等于基准数时,首先分区指示器右移一位
        //b:在a的基础上,如果当前元素下标大于分区指示器下标时,当前元素和分区指示器所指元素交换
        for (int i = start; i <= end; i++) {
            //当前元素小于基准数时
            if (nums[i] <= nums[end]){
                //分区指示器右移一位
                zoneIndex++;
                //在a的基础上,当前元素下标小于分区指示器下标时,交换元素
                if (i > zoneIndex){
                    swap(nums,i,zoneIndex);
                }
            }
        }
        return zoneIndex;
    }
    public static void swap(int[] nums,int i,int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

时间复杂度

  1. 最好情况:每次分区都能均匀划分,递归树高度为 log n。

    • 时间复杂度:O(n log n)
  2. 最坏情况:每次分区极度不平衡(如序列已有序或逆序),递归树退化为链表。

    • 时间复杂度:O(n²)
  3. 平均情况 :通过随机化基准选择(如随机选取 pivot),可避免最坏情况,平均时间复杂度为 O(n log n)

空间复杂度

  • 递归栈空间:取决于递归深度。

    • 最好情况:O(log n)(均匀分区时的栈深度)。

    • 最坏情况:O(n)(极度不平衡分区)。

  • 原地排序 :无需额外存储空间,空间复杂度主要来自递归调用。O(1)

相关推荐
linweidong1 分钟前
中科闻歌Java面试题及参考答案
java·python·大模型·提示词·ai agent·mcp·rag原理
OpenAnolis小助手7 分钟前
一句话看透 JVM,SysOM 诊断 Skill 新增 Java 应用诊断能力
java·开发语言·jvm·阿里云·操作系统控制台·sysom
ForteScarlet27 分钟前
Kotlin 2.4.20 现已发布,新特性多不多?
android·java·开发语言·开源·kotlin·jetbrains
萧瑟余晖29 分钟前
Java深入解析篇六十二之安全机制详解
java·开发语言
小刘在重生~1 小时前
Java 常用类|包装类 装箱拆箱、Integer 缓存面试题
java·python·缓存
Orange_sparkle1 小时前
Pi Agent vs LangGraph:从人机交互、企业 RAG 到持久化工作流的完整选型指南
java·网络·人机交互
Wang's Blog3 小时前
Java框架快速入门: Spring Security+OAuth2之过滤器与过滤器链
java·开发语言·spring
谢尔登3 小时前
01_Java基础速通
java·开发语言
lemon_sjdk4 小时前
javafx-Image图像(2)
java·javafx
小七在进步4 小时前
C++入门(2)
java·jvm·c++