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

合并排序算法(合并数组部分)

牟星火
2023-03-14

问题是关于从16:43到23:34的视频中的合并排序http://youtu.be/M814OagXWTI?t=16m43s

在退出左/右排序合并递归后,我不清楚我们是如何合并回这些子数组的。让我们从最底部开始,当我们的元素被分成两个子数组时,一个左子数组称为B,一个右子数组称为C。在16:43左右,我们跳转到合并函数,对数组B和C进行排序,这两个数组只有8和3。合并排序函数(下面的代码)基本上通过索引比较B和C的元素。从元素0开始,我们比较两个数组中的每个元素,并将最小的元素添加到数组A中。我们增加元素来自哪个数组的索引,等等,直到基本上有一个排序数组。在我们的排序数组完成之后,我们退出了递归调用,我们在其中爬行回到之前暂停的递归堆栈,继续拆分子数组8 3 2 9的右侧。

我们基本上做了上面所做的,然后再次退出我们所处的递归调用,继续合并38229。好的,这是我的问题:我在代码中看到了一个矛盾。我们将合并的元素反馈给数组A,但是当我们调用merge函数合并28和29时,我们传递的是数组B、C和A。然后我们使用数组B和C进行比较,但是我们要排序的元素在A中,不是吗?那么,这难道不是在分类错误的东西吗?我真的需要澄清这一点。

伪代码:

 MergeSort(A[0...n-1]){
if n<=1
    return A;

copy A[0...n/2-1] to B[0...n/2-1]
copy A[n/2...n-1] to C[0...n/2-1]
MergeSort(B[0...(n/2)-1)
MergeSort(C[0...(n/2)-1)
Merge(B,C,A)

Merge(B[0...p-1], C[0...q-1], A[0...p+q-1]){
i=0; j=0; k=0
while( i <p and j<q) do{
    if B[i] <= C[j] {
        A[k]=B[i];
        i=i+1;
    }
    else {
    A[k]=C[j];
    j=j+1;
    }
    k=k+1
}

//Copy leftover element
if i==p
    A[k...p+q-1]=C[j...q-1]
else
    A[k...p+q-1]=B[i...p-1]
}

共有1个答案

梁明辉
2023-03-14

这是一个使用引用的算法的简单排序的逐条叙述。缩进表示堆栈深度。每个MergeSort或Merge调用都按时间顺序编号。A3表示调用3中的数组。“==”表示“相当于”。“=”表示“有内容”。

假设Top有一个原始数组content{3,4,2,1}。顶部调用合并排序(原始)

MergeSort1(A1==Original={3,4,2,1}) Create B1={3,4} and C1={2,1}
  MergeSort2(A2==B1={3,4}) Create B2={3} and C2={4}
    MergeSort3(A3==B2={3}) Base case, no changes.
    MergeSort4(A4==C2={4}) Base case, no changes.
    Merge5(B5==B2={3},C5==B2={4},A5==A2==B1) Write {3,4} into A5, which is A2, which is B1.
  MergeSort6(A6==C1={2,1}) Create B6={2} and C6={1}
    MergeSort7(A7==B6={2}) Base case, no changes.
    MergeSort8(A8==C6={1}) Base case, no changes.
    Merge9(B9==B6={2},C9==C6={1},A9==A6==C1) Write {1,2} into A9, which is A6, which is C1.
  Merge10(B10==B1={3,4},C10==C1=={1,2},A10==A1==Original) Write {1,2,3,4} into A10, which is A1, which is Original.

所有这些的高级结果是用{1,2,3,4}替换原来的{3,4,2,1}。

要记住的关键点是,每个函数调用都有自己的堆栈框架,有自己的变量,但是它的形式参数映射到实际参数,该参数是调用方框架中的变量或参数。

 类似资料:
  • 我在理解外部排序算法中的合并步骤时遇到了一定的困难。我在维基百科上看到了这个例子,但我无法理解。 外部排序的一个例子是外部合并排序算法,它对每个适合RAM的块进行排序,然后将排序后的块合并在一起。例如,对于仅使用100 MB RAM对900 MB数据进行排序:1)读取主内存中的100 MB数据,并通过一些常规方法进行排序,如快速排序。2) 将排序后的数据写入磁盘。3) 重复第1步和第2步,直到所有

  • 我知道合并排序算法的基本概念,但是当涉及到通过递归实现它时,我很难理解它是如何工作的。据我所知,合并排序函数将我们当前的数组分成两半,并使用递归我们一直这样做,直到每边只剩下一个元素。 如果我们的数组是{38、27、43、3、9、82、10},那么我们的递归将从使用子数组(原始数组的左侧)调用自身开始,并每次重复该过程,将数组减半并存储最左侧,直到达到1个元素: 然后在我们的第二个子例程中,我们继

  • 我在理解合并排序算法的“合并”部分时有点困难,因为我试图在上下文中理解算法的部分,而某些变量/循环对我来说没有意义。我理解递归除法过程和合并的排序方面,但在这个特定的合并算法中: 我不明白最后3个循环: 你能解释一下这3个循环在合并的上下文中是用来做什么的吗?还有什么进一步的建议可以帮助你更好地理解合并排序算法的合并部分吗?

  • 这些是家庭作业问题,但我想了解它们背后的概念,而不仅仅是得到答案。 我知道MergeSort的运行时间是O(nlogn)。似乎合并方法必须运行 n 次(因为它必须合并所有数组,最终会有 n 个数组)。因此,我想我可以推断出 MergeSort() 方法将被称为 logn times。我也认为这是有道理的,因为它正在划分数组,所以它会一直将自己除以 2,所以 logn。 因此,我觉得答案分别是C和A

  • 我是java新手,我有任务要做——mergeSort,但我有一个老师根据数组右侧提出的问题,但我不知道该怎么做。这是我的代码: 代码运行得很完美,但是,正如我前面提到的,我的老师问我:“你处理一半的合并-请注意,你还有第二个数组(右边的一个),当左边的一个为空时,可能会有元素”。 你能告诉我我在这里做错了什么吗?谢谢你的帮助。

  • 双向合并排序与递归合并排序有何不同? 假设在合并排序中有5个数字需要排序8,9,1,6,4,我们按如下步骤1进行划分:{8,9,1}{6,4} 步骤2:{8,9}{1}{6}{4} 步骤3:{8}{9}{1}{6}{4} 现在合并 步骤4:{8,9}{1}{4,6} 步骤5:{1,8,9}{4,6} 第六步:{1,4,6,8,9} 但在双向合并排序中,我们将数组分为两个元素(但根据维基百科,在合并