【问题标题】:Merge sort algorithm(merging array part)合并排序算法(合并数组部分)
【发布时间】:2013-08-04 00:36:05
【问题描述】:

问题是关于从 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 的右侧。

我们基本上做我们上面所做的,然后再次退出我们所在的递归调用并继续合并 3 8 2 9。好的,这是我的问题:我在代码。我们将合并的元素返回给我们的数组 A,但是当我们调用合并函数来合并 2 8 和 2 9 时,我们传递了数组 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]
}

【问题讨论】:

  • A 是一个形式参数标识符,所以它在 MergeSort 的不同调用中意味着不同的东西。
  • 调用特定的 MergSort 调用 X。X 调用 MergeSort 调用 Y 对 X 的 B 进行排序。Y 调用 A,Y 离开其排序数据的地方,就是 X 调用 B。X 调用 MergeSort 调用 Z对 X 的 C 进行排序。Z 称为 A 的地方,它离开排序数据的地方,就是 X 称为 C 的地方。从 Z 返回时,X 的 B 和 C 被排序,X 将它们合并到 X 的 A 中。除非 X 是顶部级别调用,对于 X 的调用者来说是 B 或 C。
  • 你的基本问题是你假设变量和形式参数在不同的 MergeSort 调用中意味着相同的东西。您必须找到一些方法来标记不同的调用,以便您可以考虑和讨论它们的变量。如果你不喜欢 X、Y 和 Z,想想你自己的名字。只要您停止将一个调用中的 A 与另一个调用中的 A 混淆,标签就无关紧要了。根据您发布的代码,MergeSort 调用 Merge,因此当 MergeSort 调用返回时,它的 A 已排序。
  • 除了你的问题,你在第二行有一个错误:n > 1 不是基本情况,而不是返回 n,如果 n
  • 这是可能的,因为每次调用方法都会获得自己的堆栈帧,具有自己的参数值和自己的局部变量。堆栈可以同时包含十几个不同的 MergeSort 帧。

标签: arrays algorithm sorting data-structures


【解决方案1】:

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

假设 Top 有一个数组 Original,内容为 {3,4,2,1}。热门调用 MergeSort(Original)

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} 替换 Original 中的 {3,4,2,1}。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-04
    • 1970-01-01
    • 2013-08-04
    • 2013-01-06
    • 2021-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多