【问题标题】:Merge Sort Algorithm last step归并排序算法最后一步
【发布时间】:2023-01-28 06:26:42
【问题描述】:
// Sorts the sequence (A[p],...,A[r-1])
template<class T> 
void merge_sort(array<T>& A,int p,int r) 
{ 
  if (p<r-1)     
  { 
     int q=?; // see discussion in the text
     merge_sort(A,p,q);
     merge_sort(A,q,r);
     merge(A,p,q,r);
  }
}

假设数组是 [4, 9, 13, 1, 5]。我理解递归,第一个 merge_sort 方法拆分数组直到[4] 点,所以第一个和第二个合并排序方法被跳过。它怎么知道数组的其余部分在哪里合并呢?数组 A 现在只有 [4],所以如果我们调用 merge (A,p,q,r) 它只会得到 4 而没有其他部分可以与之合并?

【问题讨论】:

  • “直到 [4] 点”是什么意思?通常 merge_sorts 将数组分成两半,并递归地对下半部分和上半部分进行排序,直到它到达长度为 1 的数组。

标签: algorithm sorting merge


【解决方案1】:

数组 A 现在只有 [4] ...它只得到 4 而没有其他部分可以与之合并。

那就是混乱所在。数组不会变短!在任何时候,数组都是具有所有原始值的完整数组。

子数组的概念仅由附加参数 pr 反映。这些标志着范围对此感兴趣满的数组(其中 p 是第一个索引范围,r是第一个索引范围)。

例如,在这个递归调用中查找:

 merge_sort(A,p,q);

pq 索引标记数组 A 中我们要排序的分区的位置。该调用仅适用于数组的那一部分。

在某一时刻,我们将有 p==0q==1r==2,然后上面的调用将只查看一个元素,A[0]。

下一个递归调用是:

 merge_sort(A,q,r);

此调用还将查看一个元素:A[1]。

这两个调用只会返回(因为显然没有任何事情需要做,因为只有一个值的子数组总是“排序的”),然后合并可以通过这个调用完成:

 merge(A,p,q,r);

请注意,此合并调用开始使用两个值:A[0] 和 A[1]。当此调用返回时,我们知道索引 0 和 1 处的值现在保证按排序顺序排列。

【讨论】:

    【解决方案2】:

    merge_sort 方法递归地拆分数组,直到每个子数组只包含一个元素。每个子数组都被认为是“已排序”的,因为它只有一个元素。然后 merge 方法采用两个“已排序”的子数组(它们最初可能是较大数组的一部分)并按排序顺序将它们合并回一起。在您提供的示例中,在使用数组 [4、9、13、1、5] 初始调用 merge_sort 之后,该数组将被拆分为子数组 [4] 和 [9、13、1、5]。然后将调用 merge 方法以按排序顺序将 [4] 和 [9, 13, 1, 5] 合并回一起。 merge 方法跟踪要合并的子数组的开始、中间和结束的索引,因此它知道要将哪些元素合并在一起。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-21
      • 1970-01-01
      • 2017-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多