常见排序算法及其java实现

常见排序算法

  • [一、冒泡排序(Bubble Sort)​](#一、冒泡排序(Bubble Sort))
  • [二、选择排序(Selection Sort)​​ ​​](#二、选择排序(Selection Sort))
  • [三、插入排序(Insertion Sort)​​](#三、插入排序(Insertion Sort))
  • [四、快速排序(Quick Sort)​​ ​​](#四、快速排序(Quick Sort))
  • [五、归并排序(Merge Sort)​​ ​​](#五、归并排序(Merge Sort))
  • [六、堆排序(Heap Sort)​](#六、堆排序(Heap Sort))
  • 总结​​

以下是常见的排序算法及其 ​​Java 实现​​,包括 ​​时间复杂度、空间复杂度、稳定性​​ 分析,并附上代码示例。

一、冒泡排序(Bubble Sort)​

原理 ​​:重复比较相邻元素,较大的元素逐步"冒泡"到数组末尾。
时间复杂度​​:

  • 最好情况(已有序):O(n)
  • 平均和最坏情况:O(n²)

​​空间复杂度 ​​:​​O(1)​​(原地排序)

​​稳定性​​:​​稳定​​(相同元素相对位置不变)

java 复制代码
public void bubbleSort(int[] arr) {
    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; // 提前终止
    }
}

二、选择排序(Selection Sort)​​ ​​

原理 ​​:每次选择未排序部分的最小元素,放到已排序部分的末尾。
​​时间复杂度 ​​:​​O(n²)​​(无论数据是否有序)

​​空间复杂度 ​​:​​O(1)​​
​​稳定性​​:​​不稳定​​(可能破坏相同元素的顺序) ​​

java 复制代码
public void selectionSort(int[] arr) {
    int n = arr.length;
    for (int i = 0; i < n - 1; i++) {
        int minIndex = i;
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        // 交换
        int temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
}   

三、插入排序(Insertion Sort)​​

​​原理 ​​:将未排序元素逐个插入到已排序部分的正确位置。

​​时间复杂度​​:

  • 最好情况(已有序):O(n)
  • 平均和最坏情况:O(n²)

​​空间复杂度​​ :​​O(1)​​

​​稳定性​​:​​稳定​​ ​​

java 复制代码
public void insertionSort(int[] arr) {
    int n = arr.length;
    for (int i = 1; i < n; i++) {
        int key = arr[i];
        int j = i - 1;
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j]; // 后移
            j--;
        }
        arr[j + 1] = key; // 插入
    }
}          ​​

四、快速排序(Quick Sort)​​ ​​

原理 ​​:分治思想,选择一个基准(pivot),将数组分为小于基准和大于基准的两部分,递归排序。

​​时间复杂度​​:

  • 平均情况:O(n log n)
  • 最坏情况(如数组已有序):O(n²)(可通过随机化基准避免)

​​空间复杂度 ​​:​​O(log n)​​(递归栈开销)

​​稳定性​​:​​不稳定​​ ​​

java 复制代码
public 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 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++;
            // 交换
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }
    // 把基准放到正确位置
    int temp = arr[i + 1];
    arr[i + 1] = arr[high];
    arr[high] = temp;
    return i + 1;
}  

五、归并排序(Merge Sort)​​ ​​

原理 ​​:分治思想,将数组分为两半,分别排序后合并。

​​时间复杂度 ​​:​​O(n log n)​​(所有情况)

​​空间复杂度​​ :​​O(n)​​(需要额外数组)
​​稳定性​​:​​稳定​​

java 复制代码
public void mergeSort(int[] arr, int left, int right) {
    if (left < right) {
        int mid = left + (right - left) / 2;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid + 1, right);
        merge(arr, left, mid, right);
    }
}

private void merge(int[] arr, int left, int mid, int right) {
    int n1 = mid - left + 1;
    int n2 = right - mid;
    int[] L = new int[n1];
    int[] R = new int[n2];

    // 拷贝数据到临时数组
    for (int i = 0; i < n1; i++) L[i] = arr[left + i];
    for (int j = 0; j < n2; j++) R[j] = arr[mid + 1 + j];

    // 合并
    int i = 0, j = 0, k = left;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k] = L[i];
            i++;
        } else {
            arr[k] = R[j];
            j++;
        }
        k++;
    }

    // 处理剩余元素
    while (i < n1) arr[k++] = L[i++];
    while (j < n2) arr[k++] = R[j++];
}  

六、堆排序(Heap Sort)​

​​原理 ​​:利用堆数据结构(大顶堆/小顶堆)进行排序。

​​时间复杂度​​ :​​O(n log n)​​(所有情况)

​​空间复杂度 ​​:​​O(1)​​(原地排序)
​​稳定性​​:​​不稳定

java 复制代码
public void heapSort(int[] arr) {
    int n = arr.length;

    // 构建大顶堆
    for (int i = n / 2 - 1; i >= 0; i--) {
        heapify(arr, n, i);
    }

    // 逐个提取堆顶元素
    for (int i = n - 1; i > 0; i--) {
        // 交换堆顶和最后一个元素
        int temp = arr[0];
        arr[0] = arr[i];
        arr[i] = temp;

        // 调整堆
        heapify(arr, i, 0);
    }
}

private void heapify(int[] arr, int n, int i) {
    int largest = i; // 初始化最大元素为根节点
    int left = 2 * i + 1;
    int right = 2 * i + 2;

    // 左子节点比根大
    if (left < n && arr[left] > arr[largest]) largest = left;

    // 右子节点比根大
    if (right < n && arr[right] > arr[largest]) largest = right;

    // 如果最大值不是根节点,交换并继续调整
    if (largest != i) {
        int temp = arr[i];
        arr[i] = arr[largest];
        arr[largest] = temp;
        heapify(arr, n, largest);
    }
}

总结​​

排序算法 平均时间复杂度 最坏时间复杂度 空间复杂度 稳定性 适用场景
冒泡排序 O(n²) O(n²) O(1) 稳定 小规模数据
选择排序 O(n²) O(n²) O(1) 不稳定 小规模数据
插入排序 O(n²) O(n²) O(1) 稳定 小规模或接近有序数据
快速排序 O(n log n) O(n²) O(log n) 不稳定 大规模数据(最快)
归并排序 O(n log n) O(n log n) O(n) 稳定 大规模数据(稳定)
堆排序 O(n log n) O(n log n) O(1) 不稳定 大规模数据(原地排序)

推荐选择​​:

  • 小规模数据:插入排序(稳定)或冒泡排序(简单)。
  • 大规模数据:快速排序(最快)、归并排序(稳定)、堆排序(原地排序)。
相关推荐
神仙别闹16 分钟前
基于QT(C++)实现(图形界面)选课管理系统
java·c++·qt
daixin884817 分钟前
SpringMVC的请求执行流程是什么样的?
java·开发语言·spring
pengzhuofan26 分钟前
Web开发系列-第9章 SpringBootWeb登录认证
java·spring boot·后端·web
手握风云-43 分钟前
JavaEE初阶第十二期:解锁多线程,从 “单车道” 到 “高速公路” 的编程升级(十)
java·开发语言·java-ee
Deng9452013141 小时前
数独求解器与生成器(回溯算法实现)
算法·图形用户界面·matlab技术·数独谜题·求解器与生成器
淦暴尼1 小时前
银行客户流失预测分析
python·深度学习·算法
Swiler1 小时前
数据结构第1问:什么是数据结构?
数据结构·算法
盖世英雄酱581361 小时前
加了锁,加了事务 还是重复报名❓
java·数据库·后端
Pigwantofly1 小时前
SpringAI入门及浅实践,实战 Spring‎ AI 调用大模型、提示词工程、对话记忆、Adv‎isor 的使用
java·大数据·人工智能·spring
Eloudy1 小时前
复矩阵与共轭转置矩阵乘积及其平方根矩阵
人工智能·算法·矩阵