数据结构奇妙旅程之深入解析归并排序

归并排序(Merge Sort)是一种分治策略的排序算法,它将已有序的子序列合并,得到完全有序的序列。归并排序可以分为两个主要步骤:分解和合并。

分解步骤是将数组不断地一分为二,直到子数组只包含一个元素(此时可以认为子数组是有序的)。合并步骤则是将两个有序的子数组合并成一个有序数组,直到合并为完整的有序数组。

下面是一个归并排序的 Java 实现以及详细的代码解析:

java 复制代码
public class MergeSort {

    // 归并排序的入口函数
    public static void mergeSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return; // 如果数组为空或只有一个元素,则不需要排序
        }
        mergeSort(arr, 0, arr.length - 1); // 调用递归排序函数
    }

    // 递归排序函数
    private static void mergeSort(int[] arr, int left, int right) {
        if (left < right) {
            // 找到中间位置
            int mid = (left + right) / 2;
            // 递归分解左半部分
            mergeSort(arr, left, mid);
            // 递归分解右半部分
            mergeSort(arr, mid + 1, right);
            // 合并左右两部分
            merge(arr, left, mid, right);
        }
    }

    // 合并两个有序数组
    private static void merge(int[] arr, int left, int mid, int right) {
        // 临时数组
        int[] temp = new int[right - left + 1];
        // 左半部分有序序列的指针
        int i = left;
        // 右半部分有序序列的指针
        int j = mid + 1;
        // 临时数组的指针
        int k = 0;

        // 将左右两个有序数组合并到临时数组
        while (i <= mid && j <= right) {
            if (arr[i] <= arr[j]) {
                temp[k++] = arr[i++];
            } else {
                temp[k++] = arr[j++];
            }
        }

        // 将左边剩余元素填充进temp中
        while (i <= mid) {
            temp[k++] = arr[i++];
        }

        // 将右边剩余元素填充进temp中
        while (j <= right) {
            temp[k++] = arr[j++];
        }

        // 将temp中的元素全部拷贝回原数组
        for (int p = 0; p < temp.length; p++) {
            arr[left + p] = temp[p];
        }
    }

    public static void main(String[] args) {
        int[] arr = {5, 3, 8, 4, 2};
        mergeSort(arr);
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }
}

代码解析:

  1. mergeSort(int[] arr) 方法是归并排序的入口点,它首先检查数组是否为空或只有一个元素,如果是,则直接返回。然后调用递归排序函数 mergeSort(int[] arr, int left, int right)。

  2. mergeSort(int[] arr, int left, int right) 是一个递归方法,用于分解数组。它找到数组的中间位置,然后递归地对左半部分和右半部分进行排序。当 left < right 时,表示还有需要排序的子数组,否则递归结束。

  3. merge(int[] arr, int left, int mid, int right) 方法负责合并两个有序的子数组。它创建了一个临时数组 temp,并用两个指针 i 和 j 分别指向左右两个子数组的起始位置。然后,比较这两个子数组的元素,并将较小的元素放入 temp 中,直到其中一个子数组的所有元素都被放入 temp。最后,将另一个子数组剩余的元素也放入 temp,并将 temp 中的元素复制回原数组。

  4. main 方法中创建了一个待排序的数组,并调用 mergeSort 方法进行排序。排序完成后,遍历数组并打印排序结果。

归并排序是一种稳定的排序算法,时间复杂度为 O(n log n),其中 n 是数组的长度。由于归并排序涉及递归和额外的数组空间,因此空间复杂度也是 O(n)。尽管归并排序在大多数情况下表现优异,但在处理小数组或几乎有序的数组时,

相关推荐
Evand J几秒前
【PMSM例程6】永磁同步电机(PMSM)基于增广EKF的d-q轴电感分阶段辨识算法|电机参数估计与误差分析
算法·matlab·电机·ekf
垆边人似月.2 分钟前
华为题:最多可以参加的会议数目
数据结构·c++·算法
Tongzhi20262 分钟前
2026 年考勤行业趋势:考勤正在从“打卡工具“变成“人力成本中枢“
大数据·数据结构·数据仓库·科技·数据库开发
Matlab程序猿5 分钟前
【MATLAB源码-第460期】基于matlab的OTFS通信系统SLM峰均比抑制及非线性功率放大器失真与误码性能仿真
开发语言·算法·matlab·slm·otfs
xiangyun616 分钟前
C++ list 模拟实现(一):手撕双向链表,从节点到迭代器
数据库·c++·算法·链表·stl·list
码爸9 小时前
线性回归算法
算法·机器学习·线性回归
Coder-magician9 小时前
《代码随想录》刷题打卡day51:图论-part09(dijistra堆优化,Bellman_ford算法)
算法·图论
Nil2089 小时前
leetcode 763划分字母区间
算法·leetcode·职场和发展
不会就选b10 小时前
算法日常・每日刷题--<动态规划>20
算法·leetcode·动态规划
青少儿编程课堂11 小时前
迪杰斯特拉(Dijkstra)算法:单源最短路与赛场路线规划
c++·python·算法·bfs·信息学竞赛