【算法系列】归并排序详解

文章目录

  • 归并排序详解
    • [1. 基本原理](#1. 基本原理)
      • [1.1 分治法策略](#1.1 分治法策略)
      • [1.2 归并排序步骤](#1.2 归并排序步骤)
      • [1.3 图解示例](#1.3 图解示例)
    • [2. 时间复杂度与空间复杂度](#2. 时间复杂度与空间复杂度)
      • [2.1 时间复杂度](#2.1 时间复杂度)
      • [2.2 空间复杂度](#2.2 空间复杂度)
    • [3. 稳定性](#3. 稳定性)
    • [4. Java 实现示例](#4. Java 实现示例)
    • [5. 归并排序的优点与缺点](#5. 归并排序的优点与缺点)
      • [5.1 优点](#5.1 优点)
      • [5.2 缺点](#5.2 缺点)
    • [6. 总结](#6. 总结)

归并排序详解

归并排序(Merge Sort)是一种基于分治法的经典排序算法。它通过递归地将数组分成较小的子数组,分别对这些子数组进行排序,然后将它们合并以产生最终的有序数组。归并排序以其稳定性和在最坏情况下的高效性能而著称。

1. 基本原理

1.1 分治法策略

归并排序的核心思想是分治法,即将一个问题分解成若干个规模更小但类似的子问题,递归地解决这些子问题,然后将结果合并以得到原问题的解。

1.2 归并排序步骤

  1. 分割:将数组不断分割成两个大致相等的部分,直到每个部分只有一个元素。
  2. 排序:对每个单独的元素视为已排序的部分。
  3. 合并:将两个已排序的子数组合并成一个更大的已排序数组,直到整个数组排序完成。

1.3 图解示例

假设我们有一个数组 [8, 4, 5, 7, 1, 3, 6, 2],以下是归并排序的过程:

2. 时间复杂度与空间复杂度

2.1 时间复杂度

  • 最好、平均和最坏情况:O(n log n)
  • 每次分割操作的时间复杂度为 O(log n),每次合并操作的时间复杂度为 O(n)。

2.2 空间复杂度

  • 空间复杂度:O(n)
  • 需要额外的空间来存储临时数组,在合并过程中使用。

3. 稳定性

归并排序是稳定的排序算法,即相同值的相对位置不会改变。

4. Java 实现示例

java 复制代码
public static void mergeSort(int[] arr) {
    int[] temp = new int[arr.length];
    mergeSort(arr, 0, arr.length - 1, temp);
}

private static void mergeSort(int[] arr, int l, int r, int[] temp) {
    if(l < r) {
        int m = (l + r) / 2;
        mergeSort(arr, l, m, temp);
        mergeSort(arr, m + 1, r, temp);
        merge(arr, l, m, r, temp);
    }
}

private static void merge(int[] arr, int l, int m, int r, int[] temp) {
    int i = l; // 左序列指针
    int j = m + 1; // 右序列指针
    int k = l;
    while(i <= m && j <= r) {
        if(arr[i] <= arr[j]) {
            temp[k++] = arr[i++];
        } else {
            temp[k++] = arr[j++];
        }
    }

    // 左序列剩余元素填充至临时数组
    while(i <= m) {
        temp[k++] = arr[i++];
    }

    // 右序列剩余元素填充至临时数组
    while(j <= r) {
        temp[k++] = arr[j++];
    }

    // 将临时数组的数据拷贝至原数组
    k = l;
    while(k <= r) {
        arr[k] = temp[k++];
    }
}

5. 归并排序的优点与缺点

5.1 优点

稳定性:归并排序是稳定的排序算法,适合对稳定性有要求的应用场景。

时间复杂度:无论数据是否有序,归并排序的时间复杂度始终为 O(n log n),这使得它在处理大规模数据时表现良好。

适用范围广:适用于各种类型的数据集,尤其是当数据量较大且需要稳定排序时。

5.2 缺点

空间复杂度较高:归并排序需要额外的 O(n) 空间来存储临时数组,这在内存有限的情况下可能是一个限制。

递归调用栈深度:递归调用栈的深度为 O(log n),在极端情况下可能导致栈溢出。

6. 总结

归并排序是一种非常高效的排序算法,特别适合处理大规模数据集。尽管它的空间复杂度较高,但由于其稳定性和一致的时间复杂度,使其成为许多实际应用中的首选排序算法之一。

相关推荐
机器学习之心2 小时前
多目标鲸鱼优化算法(NSWOA),含46种测试函数和9个评价指标,MATLAB实现
算法·matlab·多目标鲸鱼优化算法·46种测试函数·9个评价指标
max5006003 小时前
基于Meta Llama的二语习得学习者行为预测计算模型
人工智能·算法·机器学习·分类·数据挖掘·llama
callJJ3 小时前
从 0 开始理解 Spring 的核心思想 —— IoC 和 DI(2)
java·开发语言·后端·spring·ioc·di
wangjialelele3 小时前
Linux中的线程
java·linux·jvm·c++
谷咕咕3 小时前
windows下python3,LLaMA-Factory部署以及微调大模型,ollama运行对话,开放api,java,springboot项目调用
java·windows·语言模型·llama
没有bug.的程序员3 小时前
MVCC(多版本并发控制):InnoDB 高并发的核心技术
java·大数据·数据库·mysql·mvcc
在下村刘湘4 小时前
maven pom文件中<dependencyManagement><dependencies><dependency> 三者的区别
java·maven
王哥儿聊AI4 小时前
Lynx:新一代个性化视频生成模型,单图即可生成视频,重新定义身份一致性与视觉质量
人工智能·算法·安全·机器学习·音视频·软件工程
不务专业的程序员--阿飞5 小时前
JVM无法分配内存
java·jvm·spring boot
李昊哲小课5 小时前
Maven 完整教程
java·maven