快速排序算法详解

算法思想

快速排序是一种高效的排序算法,采用分治策略​(Divide and Conquer)。它的基本思想是:

  1. 选择一个基准元素(pivot)

  2. 将数组分区,使得所有小于基准的元素都在其左侧,所有大于基准的元素都在其右侧

  3. 递归地对左右两个子数组进行快速排序

算法步骤

  1. ​选择基准​:从数组中选择一个元素作为基准(pivot)

  2. ​分区操作​:重新排列数组,使所有小于基准的元素放在基准前面,所有大于基准的元素放在基准后面

  3. ​递归排序​:递归地将上述过程应用于基准左右两侧的子数组

Java实现

复制代码
public class QuickSort {
    
    // 快速排序入口方法
    public static void quickSort(int[] arr) {
        if (arr == null || arr.length == 0) {
            return;
        }
        quickSort(arr, 0, arr.length - 1);
    }
    
    // 递归快速排序
    private static void quickSort(int[] arr, int low, int high) {
        if (low < high) {
            // 分区操作,返回基准的索引位置
            int pivotIndex = partition(arr, low, high);
            
            // 递归排序左半部分
            quickSort(arr, low, pivotIndex - 1);
            
            // 递归排序右半部分
            quickSort(arr, pivotIndex + 1, high);
        }
    }
    
    // 分区函数
    private static int partition(int[] arr, int low, int high) {
        // 选择最右边的元素作为基准
        int pivot = arr[high];
        
        // 小于基准的元素的边界索引
        int i = low - 1;
        
        for (int j = low; j < high; j++) {
            // 如果当前元素小于或等于基准
            if (arr[j] <= pivot) {
                i++;
                // 交换arr[i]和arr[j]
                swap(arr, i, j);
            }
        }
        
        // 将基准元素放到正确位置
        swap(arr, i + 1, high);
        
        return i + 1;
    }
    
    // 交换数组中两个元素的位置
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    
    // 测试代码
    public static void main(String[] args) {
        int[] arr = {64, 34, 25, 12, 22, 11, 90};
        
        System.out.println("排序前的数组:");
        printArray(arr);
        
        quickSort(arr);
        
        System.out.println("排序后的数组:");
        printArray(arr);
    }
    
    // 打印数组
    private static void printArray(int[] arr) {
        for (int value : arr) {
            System.out.print(value + " ");
        }
        System.out.println();
    }
}

时间复杂度分析

  • ​最佳情况​:O(n log n) - 每次分区都能将数组均匀分成两部分

  • ​平均情况​:O(n log n)

  • ​最坏情况​:O(n²) - 当数组已经有序或逆序,且选择最边缘的元素作为基准时

空间复杂度

  • 平均情况下:O(log n) - 递归调用栈的空间

  • 最坏情况下:O(n) - 需要n层递归调用

优化策略

  1. ​随机选择基准​:随机选择基准元素可以避免最坏情况的发生

  2. ​三数取中法​:选择第一个、中间和最后一个元素的中值作为基准

  3. ​小数组使用插入排序​:当子数组规模较小时(如<10),使用插入排序更高效

  4. ​尾递归优化​:减少递归深度

算法特点

  • ​不稳定排序​:相等元素的相对位置可能会改变

  • ​原地排序​:只需要常数级的额外空间

  • ​实践中最快​:尽管最坏情况时间复杂度较高,但在实际应用中通常是最快的排序算法

快速排序因其高效性和实用性,被广泛应用于各种编程语言和系统的排序实现中。

相关推荐
罗西的思考4 分钟前
机器人 / 物理 Agent Harness 综合分析与对比:从「更强的模型」到「更好的系统」
人工智能·算法·机器学习
库玛西5 分钟前
攻克 408 数据结构:图论基石深度拆解(数学极值推演 + 存储内存剖析 + BFS/DFS 双核模板)
数据结构·算法·深度优先·广度优先·图搜索算法
倒头就睡的小比特5 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!5 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼5 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
m0_547486665 天前
《数据结构教程》全套 PPT课件2026
数据结构
旖旎夜光5 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark5 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her15 天前
并查集-听课笔记
笔记·算法·并查集
码流子6 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构