排序(3)-第三篇:交换排序专题——从冒泡排序到快速排序的效率飞跃

📌 引言

交换排序,顾名思义,核心操作就是通过"两两比较并交换"来达到有序的目的 。这一族群里有两个极具代表性的选手:一个是无数人的启蒙算法------冒泡排序 ;另一个则是工业界、面试官长盛不衰的宠儿------快速排序。它们之间,是一场关于执行效率的惊艳飞跃。

1. 冒泡排序(Bubble Sort)

💡 核心思想

从左到开依次比较相邻的两个数,如果前面的数比后面的大,就交换它们。这样一轮下来,当前区间的最大值就像"气泡"一样浮到了数组的最右端。

💻 Java 代码实现(带提前跳出优化)
复制代码
public class BubbleSort {
    public static void sort(int[] arr) {
        if (arr == null || arr.length < 2) return;
        int n = arr.length;
        
        for (int i = 0; i < n - 1; i++) {
            boolean swapped = false; // 优化:若某一趟没有发生任何交换,说明已经有序了
            for (int j = 0; j < n - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    swapped = true;
                }
            }
            if (!swapped) break; 
        }
    }
}

2. 快速排序(Quick Sort)

🚀 为什么叫快速排序?

冒泡排序太慢了,因为每次交换只能解决相邻 两个元素的无序问题。而快速排序采用分治思想(Divide and Conquer),通过选择一个"基准值",让大小元素横跨大半个数组进行对调,从而实现大步流星的排序。

💡 核心思想
  1. 找基准(Pivot): 通常选区间第一个数作为基准。

  2. 分区(Partition): 通过双指针左右开弓,把比 Pivot 小的扔到左边,比 Pivot 大的扔到右边。

  3. 递归(Solve): 此时 Pivot 已经锁定了它的最终位置。接下来对左、右两部分分别重复上述过程。

💻 Java 代码实现(标准双指针法)
复制代码
public class QuickSort {
    public static void sort(int[] arr) {
        if (arr == null || arr.length < 2) return;
        quickSort(arr, 0, arr.length - 1);
    }

    private static void quickSort(int[] arr, int low, int high) {
        if (low >= high) return;
        
        // 核心切分操作,返回基准值的最终正确索引
        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[low]; 
        int i = low, j = high + 1;
        
        while (true) {
            // 左指针向右找第一个比 pivot 大的数
            while (arr[++i] < pivot) if (i == high) break;
            // 右指针向左找第一个比 pivot 小的数
            while (pivot < arr[--j]) if (j == low) break;
            
            if (i >= j) break; // 指针相遇,退出循环
            swap(arr, i, j);   // 交换这两个错位的数
        }
        swap(arr, low, j); // 将基准值交换到它的最终正确位置 `j`
        return j; 
    }

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

📊 交换排序大比拼

算法 最好时间复杂度 最坏时间复杂度 平均时间复杂度 空间复杂度 稳定性
冒泡排序 O(n) O(n^2) O(n^2) O(1) 稳定
快速排序 O(n \log n) O(n^2) O(n \log n) O(\log n) (递归栈) 不稳定
相关推荐
xiaohaiAIgeo22 分钟前
【2026年】ASHRAE 110与EN 14175通风柜测试标准对比:进口与国产品牌性能差距
java·前端·数据库·科普知识
wuyk55527 分钟前
1.栈:后进先出的线性数据结构
c语言·数据结构·stm32·单片机
测试_AI_一辰42 分钟前
AI Agent 评测最隐蔽的坑-记忆
人工智能·算法·ai·自动化·ai编程
lucas_AI1 小时前
给YOLO检测器插 LoRA,'插对地方'比'插什么'更要命
人工智能·算法
AI人工智能+电脑小能手1 小时前
大白话说Java设计模式-08-建造者模式(业务实战篇)
java·设计模式·建造者模式·架构设计·对象构建
LuminousCPP1 小时前
数据结构-时间与复杂度|时间/空间复杂度 + 两道力扣练习 + 二分查找复盘
c语言·数据结构·经验分享·算法·leetcode
Nil2081 小时前
leetcode 三数之和
数据结构·算法·leetcode
xbgRS1 小时前
java中的线程
java
小小龙学IT2 小时前
C++ std::vector 底层实现深度解析:内存布局、扩容策略、移动语义与迭代器失效
开发语言·c++·算法
eBest数字化转型方案2 小时前
从工程视角拆解冰柜资产管理:拍照识别 pipeline、纯净度算法与 IoT 选型踩坑
人工智能·物联网·算法