Java 中的合并(归并)排序-Merge Sort

1. 引言

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

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

2. 算法

**合并排序是一种“分而治之”的算法,我们首先将问题划分为子问题。**当子问题的解决方案准备就绪时,我们将它们组合在一起以获得问题的最终解决方案。

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

我们可以将该算法描述为以下 2 步过程:
**除法:在此步骤中,我们将输入数组分成两半,**枢轴是数组的中点。此步骤以递归方式对所有半数组执行,直到没有更多的半数组要分割。
征服:在此步骤中,我们将分割后的数组从下到上排序并合并,并得到排序后的数组。
下图显示了示例数组 {10, 6, 8, 5, 7, 3, 4} 的完整合并排序过程。

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

合并排序 1
在这里插入图片描述

3. 实现

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

基本条件检查数组长度是否为 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),因为我们在每个递归调用中创建临时数组。

  1. 结论
    在这篇简短的文章中,我们探讨了合并排序算法以及如何在 Java 中实现它。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
合并排序(Merge Sort)是一种使用分治策略的排序算法。它将待排序的数组不断划分为两个子数组,直到每个子数组只包含一个元素,然后再将这些子数组按照大小顺序归并成一个有序数组。 在Java实现合并排序算法,可以按照以下步骤进行: 1. 定义一个合并排序方法,接收一个待排序的数组作为参数。 2. 在合并排序方法内部,先判断数组的长度是否为1,如果是则返回该数组,表示已经有序。 3. 如果数组长度大于1,则将数组划分为两个子数组,分别是左子数组和右子数组。可以使用数组的拷贝来实现,左子数组从索引0开始,长度为数组长度的一半,右子数组从索引数组长度的一半开始,长度为数组长度减去一半。 4. 使用递归调用合并排序方法,对左子数组和右子数组进行排序。 5. 定义一个合并数组的方法,接收左子数组和右子数组作为参数。在该方法内部创建一个新的数组来存放合并后的结果。 6. 定义两个指针,分别指向左子数组和右子数组的起始位置。 7. 比较左子数组和右子数组的当前元素,将较小的元素放入结果数组,并将相应的指针向后移动。 8. 重复执行步骤7,直到其一个子数组的元素全部放入结果数组。 9. 将另一个子数组剩余的元素依次放入结果数组。 10. 返回结果数组,表示合并排序完成。 使用以上步骤,就可以实现合并排序算法的Java代码。通过递归不断划分和合并数组,可以在时间复杂度为O(nlogn)的情况下实现对数组的排序。CSDN上可能会有更为详细的代码实现和讲解,供参考并进一步了解合并排序的具体实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值