【问题标题】:Merge sort algorithm using recursion使用递归的合并排序算法
【发布时间】:2015-01-09 19:12:10
【问题描述】:

我正在做奥丁计划。练习题是:使用递归创建归并排序算法。以下是根据某人的解决方案修改的:

def merge_sort(arry)
  # kick out the odds or kick out of the recursive splitting?
  # I wasn't able to get the recombination to work within the same method.
  return arry if arry.length == 1
  arry1 = merge_sort(arry[0...arry.length/2])
  arry2 = merge_sort(arry[arry.length/2..-1])
  f_arry = []
  index1 = 0 # placekeeper for iterating through arry1
  index2 = 0 # placekeeper for iterating through arry2
  # stops when f_arry is as long as combined subarrays
  while f_arry.length < (arry1.length + arry2.length)
    if index1 == arry1.length
      # pushes remainder of arry2 to f_arry
      # not sure why it needs to be flatten(ed)!
      (f_arry << arry2[index2..-1]).flatten!
    elsif index2 == arry2.length
      (f_arry << arry1[index1..-1]).flatten!
    elsif arry1[index1] <= arry2[index2]
      f_arry << arry1[index1]
      index1 += 1
    else
      f_arry << arry2 [index2]
      index2 += 1
    end
  end
  return f_arry
end
  1. 第一行 return arry if arry.length == 1 是否将其从数组的递归拆分中踢出,然后绕过方法的递归拆分部分返回重组部分?似乎它应该在它递归到该部分后继续重新拆分它。

  2. 为什么一定要flatten-ed?

【问题讨论】:

    标签: ruby recursion mergesort


    【解决方案1】:

    理解第一行的最简单方法是理解merge_sort 绑定的唯一合约是“返回排序数组” - 如果数组只有一个元素 (arry.length == 1) 它是 已经排序 - 所以什么都不需要做!只需返回数组本身。

    在递归中,这称为“停止条件”。如果您不提供停止条件 - 递归将永远不会结束(因为它总是会调用自己 - 并且永远不会返回)!

    您需要flatten 的结果是因为您将数组作为元素推送到结果数组中:

    arr = [1]
    arr << [2, 3]
    # => [1, [2, 3]]
    

    如果您仅在迭代结束时尝试展平生成的数组,而不是在添加元素时,您将遇到问题,因为它的 长度 会倾斜:

    arr = [1, [2, 3]]
    arr.length
    # => 2
    

    虽然arr 包含三个数字,但它只有两个元素 - 这会破坏您的解决方案。

    您希望数组中的所有元素都是数字,而不是数组。 flatten! 确保数组中的所有元素都是原子,如果不是,它会将子数组的元素添加到自身而不是子数组:

    arr.flatten!
    # => [1, 2, 3]
    

    您可能要考虑的另一个选项(并且会更有效)是改用concat

    arr = [1]
    arr.concat([2, 3])
    # => [1, 2, 3]
    

    此方法将作为参数传递的数组中的所有元素添加到调用它的数组中。

    【讨论】:

    • 这就是我遇到的问题:
    • @spectre6000 - 在哪里?
    • 假设传入的数组 [1,2,3,4] 按照我的理解遍历:向下钻取递归,直到有 4 个单数数组。 if 语句捕获它并返回四个一数数组;它们已经排序,所以这就是停止条件。得到那部分。我迷失了大约一步左右。然后,底部步骤将单个数组重新组合成两组,每组两个,但下一步必须重新组合这两个... SORTED 组!点击。我明白为什么并且它需要 .flatten(ed)!,我不太明白为什么它需要在那个确切的位置......
    • 不小心提交了第一个回复,然后花了太长时间来编辑它...抱歉。
    • Concat 也更干净漂亮。也谢谢你!
    猜你喜欢
    • 1970-01-01
    • 2015-07-12
    • 1970-01-01
    • 2015-01-21
    • 2017-12-22
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 2019-01-22
    相关资源
    最近更新 更多