Java中的归并排序

2025/04/09

1. 简介

在本教程中,我们将了解归并排序算法及其在Java中的实现

归并排序是最有效的排序技术之一,它基于“分而治之”范式

2. 算法

归并排序是一种“分而治之”的算法,我们首先将问题分成几个子问题,当子问题的解决方案准备好后,我们将它们组合在一起,得到问题的最终解决方案。

我们可以使用递归轻松地实现该算法,因为我们处理的是子问题而不是主问题。

我们可以将该算法描述为以下两步过程:

  • 划分:在此步骤中,我们将输入数组分成两半,主元组是数组的中点;对所有半数组递归执行此步骤,直到没有更多半数组可划分。
  • 合并:这一步,我们将分割后的数组从下往上进行排序、合并,得到排好序的数组

下图显示了示例数组{10,6,8,5,7,3,4}的完整归并排序过程。

如果我们仔细观察该图,可以看到数组被递归地分成两半,直到大小变为1。一旦大小变为1,合并过程就会开始执行并在排序的同时开始合并数组:

3. 实现

为了实现,我们将编写一个mergeSort函数,该函数以输入数组及其长度作为参数。这将是一个递归函数,因此我们需要基数和递归条件。

基本条件检查数组长度是否为1,如果为1则返回,其余情况则执行递归调用。

对于递归情况,我们获取中间索引并创建两个临时数组l[]和r[],然后我们对两个子数组递归调用mergeSort函数:

public static void mergeSort(int[] a, int n) {
    if (n < 2) {
        return;
    }
    int mid = n / 2;
    int[] l = new int[mid];
    int[] r = new int[n - mid];

    for (int i = 0; i < mid; i++) {
        l[i] = a[i];
    }
    for (int i = mid; i < n; i++) {
        r[i - mid] = a[i];
    }
    mergeSort(l, mid);
    mergeSort(r, n - mid);

    merge(a, l, r, mid, n - mid);
}

接下来,我们调用merge函数,该函数接收输入和两个子数组,以及两个子数组的起始和结束索引

merge函数逐个比较两个子数组的元素,并将较小的元素放入输入数组中

当我们到达其中一个子数组的末尾时,另一个数组中的其余元素将被复制到输入数组中,从而给我们最终的排序数组:

public static void merge(int[] a, int[] l, int[] r, int left, int right) {
    int i = 0, j = 0, k = 0;
    while (i < left && j < right) {
        if (l[i] <= r[j]) {
            a[k++] = l[i++];
        }
        else {
            a[k++] = r[j++];
        }
    }
    while (i < left) {
        a[k++] = l[i++];
    }
    while (j < right) {
        a[k++] = r[j++];
    }
}

该程序的单元测试是:

@Test
public void positiveTest() {
    int[] actual = { 5, 1, 6, 2, 3, 4 };
    int[] expected = { 1, 2, 3, 4, 5, 6 };
    MergeSort.mergeSort(actual, actual.length);
    assertArrayEquals(expected, actual);
}

4. 复杂度

由于归并排序是一种递归算法,其时间复杂度可以表示为以下递归关系:

T(n) = 2T(n/2) + O(n)

2T(n / 2)对应对子数组进行排序所需的时间,O(n)是合并整个数组的时间。

求解后时间复杂度为O(nLogn)

对于最坏、平均和最好情况都是如此,因为它总是将数组分成两部分然后合并。

该算法的空间复杂度为O(n),因为我们在每次递归调用中都会创建临时数组。

5. 总结

在这篇简短的文章中,我们探讨了归并排序算法以及如何在Java中实现它。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章