Java算法系列第十二篇:归并排序算法详解

归并排序(Merge Sort)是一种基于分治法的排序算法。它通过将数组分成若干子序列,对每个子序列进行排序,然后再将它们合并为一个有序的序列。归并排序具有稳定性和较好的时间复杂度,适用于大规模数据的排序。本文将详细介绍归并排序的原理、实现及其优化方法。

一、归并排序的基本原理

归并排序的基本步骤如下:

  1. 分割:将序列递归地分成两半,直到每个子序列只包含一个元素。
  2. 合并:将两个有序子序列合并为一个有序序列。

归并排序的时间复杂度为O(n log n),空间复杂度为O(n)。

二、归并排序的实现

下面是一个用Java实现的归并排序算法:

public class MergeSort {

    // 归并排序主方法
    public 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);
        }
    }

    // 合并两个有序子序列
    public static 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;
        int 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];
            i++;
            k++;
        }

        while (j < n2) {
            arr[k] = R[j];
            j++;
            k++;
        }
    }

    public static void main(String[] args) {
        int[] arr = {12, 11, 13, 5, 6, 7};
        System.out.println("排序前:");
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();

        mergeSort(arr, 0, arr.length - 1);

        System.out.println("排序后:");
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }
}
运行结果
排序前:
12 11 13 5 6 7 
排序后:
5 6 7 11 12 13 
三、归并排序的优化方法

归并排序的性能可以通过以下优化方法进一步提升:

  1. 小数组优化:当子序列长度较小时,使用插入排序替代归并排序。
  2. 原地归并:使用原地归并算法减少空间复杂度。
小数组优化示例:
public class OptimizedMergeSort {

    private static final int THRESHOLD = 7; // 阈值

    public static void mergeSort(int[] arr, int left, int right) {
        if (right - left <= THRESHOLD) {
            insertionSort(arr, left, right);
            return;
        }

        if (left < right) {
            int mid = (left + right) / 2;
            mergeSort(arr, left, mid);
            mergeSort(arr, mid + 1, right);
            merge(arr, left, mid, right);
        }
    }

    // 插入排序方法
    public static void insertionSort(int[] arr, int left, int right) {
        for (int i = left + 1; i <= right; i++) {
            int key = arr[i];
            int j = i - 1;
            while (j >= left && arr[j] > key) {
                arr[j + 1] = arr[j];
                j = j - 1;
            }
            arr[j + 1] = key;
        }
    }

    // 合并两个有序子序列
    public static 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;
        int 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];
            i++;
            k++;
        }

        while (j < n2) {
            arr[k] = R[j];
            j++;
            k++;
        }
    }

    public static void main(String[] args) {
        int[] arr = {12, 11, 13, 5, 6, 7};
        System.out.println("排序前:");
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();

        mergeSort(arr, 0, arr.length - 1);

        System.out.println("排序后:");
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }
}
四、总结

归并排序是一种稳定且高效的排序算法,特别适合处理大规模数据。通过适当的优化,可以进一步提升其性能。在实际应用中,归并排序常用于外部排序和大数据处理。

希望大家多多点赞、关注和收藏!你的支持是我持续创作的动力!下期我们将详细讲解基数排序算法,敬请期待!


这篇文章详细介绍了归并排序的原理、实现及其优化方法。如果你有任何问题或建议,欢迎在评论区留言!

Java算法系列

  1. Java算法系列第一篇:排序算法概述与实现

  2. Java算法系列第二篇:快速排序算法详解

  3. Java算法系列第三篇:归并排序算法详解

  4. Java算法系列第四篇:堆排序算法详解

  5. Java算法系列第五篇:插入排序算法详解

  6. Java算法系列第六篇:选择排序算法详解

  7. Java算法系列第七篇:桶排序算法详解

  8. Java算法系列第八篇:基数排序算法详解

  9. Java算法系列第九篇:计数排序算法详解

  10. Java算法系列第十篇:希尔排序算法详解

  11. Java算法系列第十一篇:计数排序算法详解

  12. Java算法系列第十二篇:归并排序算法详解

  13. Java算法系列第十三篇:树排序算法详解

  14. Java算法系列第十四篇:外部排序算法详解

  15. Java算法系列第十五篇:分布式排序算法详解

  16. Java算法系列第十六篇:贪心算法详解

  17. Java算法系列第十七篇:动态规划详解

  18. Java算法系列第十八篇:图算法中的最短路径算法

  19. Java算法系列第十九篇:最小生成树算法详解

  20. Java算法系列第二十篇:图遍历算法详解

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐