当前位置: 首页 > 知识库问答 >
问题:

无法理解如何递归合并排序

丁俊爽
2023-03-14

目前正在用Daniel Liang的C++入门自学C++。

关于合并排序的话题,我似乎无法理解他的代码是如何递归调用自己的。

我理解合并排序的一般概念,但我很难具体理解这段代码。

在本例中,我们首先将列表1,7,3,4,9,3,3,1,2及其大小(9)传递给mergeSort函数。从那里,我们将列表一分为二,直到数组大小达到1。在这种情况下,我们会得到:1,7,3,4->1,7->1。然后我们进入合并排序后半部分。在这种情况下,第二个半数组将是7。我们合并两个数组[1]和[7],然后删除为防止内存泄漏而动态分配的两个数组。

我不明白的部分是这段代码是如何从这里运行的?delete[]firstthalf和delete[]secondhalf之后。根据我的理解,难道不应该有另一个mergeSort函数调用,以便合并排序新的firstHalf和secondhalf吗?

#include <iostream>
using namespace std;

// Function prototype
void arraycopy(int source[], int sourceStartIndex,
  int target[], int targetStartIndex, int length);

void merge(int list1[], int list1Size,
  int list2[], int list2Size, int temp[]);

// The function for sorting the numbers 
void mergeSort(int list[], int arraySize)
{
  if (arraySize > 1)
  {
    // Merge sort the first half
    int* firstHalf = new int[arraySize / 2];
    arraycopy(list, 0, firstHalf, 0, arraySize / 2);
    mergeSort(firstHalf, arraySize / 2);

    // Merge sort the second half
    int secondHalfLength = arraySize - arraySize / 2;
    int* secondHalf = new int[secondHalfLength];
    arraycopy(list, arraySize / 2, secondHalf, 0, secondHalfLength);
    mergeSort(secondHalf, secondHalfLength);

    // Merge firstHalf with secondHalf
    merge(firstHalf, arraySize / 2, secondHalf, secondHalfLength,
      list);

    delete [] firstHalf;
    delete [] secondHalf;
  }
}

void merge(int list1[], int list1Size,
  int list2[], int list2Size, int temp[])
{
  int current1 = 0; // Current index in list1
  int current2 = 0; // Current index in list2
  int current3 = 0; // Current index in temp

  while (current1 < list1Size && current2 < list2Size)
  {
    if (list1[current1] < list2[current2])
      temp[current3++] = list1[current1++];
    else
      temp[current3++] = list2[current2++];
  }

  while (current1 < list1Size)
    temp[current3++] = list1[current1++];

  while (current2 < list2Size)
    temp[current3++] = list2[current2++];
}

void arraycopy(int source[], int sourceStartIndex,
  int target[], int targetStartIndex, int length)
{
  for (int i = 0; i < length; i++)
  {
    target[i + targetStartIndex] = source[i + sourceStartIndex];
  }
}

int main()
{
  const int SIZE = 9;
  int list[] = {1, 7, 3, 4, 9, 3, 3, 1, 2};
  mergeSort(list, SIZE);
  for (int i = 0; i < SIZE; i++)
    cout << list[i] << " ";

  return 0;
}  

共有1个答案

井旺
2023-03-14

根据我的理解,难道不应该有另一个mergeSort函数调用,以便合并排序新的firstHalf和secondhalf吗?

它是在递归调用期间隐式发生的。当你到达这两条线时:

delete [] firstHalf;
delete [] secondHalf;

这意味着对mergeSort的一次调用已完成。如果此调用属于合并前半部分,则代码从后面的行开始,即这些行:

// Merge sort the second half
int secondHalfLength = arraySize - arraySize / 2;
...

但是,如果该调用属于后半部分的合并,则控制返回到紧随该调用之后的行,即这些行:

// Merge firstHalf with secondHalf
merge(firstHalf, arraySize / 2, secondHalf, secondHalfLength,
  list);

如果一切都按计划进行的话。

 类似资料:
  • 我有个小问题。我尝试实现合并排序算法递归。 现在我的问题: 左=合并排序(rrays.copyOfRange(iv_sort_list,0,iv_sort_list.length));右=合并排序(rrays.copyOfRange(iv_sort_list,iv_sort_list.length,iv_sort_list.length)); 如果我尝试分配我的左/右数组“mergeSort(..

  • 我正在尝试编写一个ruby方法,它可以递归地执行合并排序。我有这个方法,但这是一次我偶然得到它的工作,所以我不知道它为什么工作,并很想了解我写的代码是如何工作的。在psuedocode中,我遵循的步骤如下所示。 拆分长度为n的原始数组,直到我拥有长度为1的n个数组 一次合并和排序长度为m的2个数组,以返回长度为m*2的数组 重复上述步骤,直到我有一个长度为n的当前排序数组 基本上,在我看来,这是一

  • 我在我的应用程序中有以下合并排序代码。我对递归方法在不满足if条件时从if块中出来后如何再次调用感到非常困惑。 我调试了我的代码,但我仍然没有得到它。调用mergesort(0,号-1)的排序方法首先从mergesort(0,5)开始。低小于高,中间是2,所以接下来运行mergesort(0,2)。这一直持续到我们有mergesort(0,0),在这种情况下,低不小于高,所以它来自if块。但是当我

  • 为什么我在输出中得到一个额外的1*1,这有点倒退?有点像递归初学者,希望得到详细的答案。 输出

  • 本文向大家介绍C#递归算法之归并排序,包括了C#递归算法之归并排序的使用技巧和注意事项,需要的朋友参考一下 归并排序是利用递归和分而治之的技术将数据序列划分成为越来越小的半子表,再对半子表排序,最后再用递归步骤将排好序的半子表合并成为越来越大的有序序列,归并排序包括两个步骤,分别为: 1)划分子表 2)合并半子表 首先我们来讨论归并算法,归并算法将一系列数据放到一个向量中,索引范围为[first,

  • 我正在尝试理解递归排序函数,它是mergesort算法的一部分。下面是我的代码,我几乎可以肯定它是正确的(通过在线课程)。 我理解合并的作用——它将每个子数组分解成两个较小的子数组,重复这个过程,直到子数组的长度为1(根据定义排序),然后合并。然而,这个排序函数用来完成这个任务的实际方法对我来说很难理解。也许是因为我不习惯递归函数,但是我想知道是否有人可以在第一次合并发生时阐明操作的顺序和参数是什