【问题标题】:How is the final array constructed in this Ruby quicksort implementation?这个 Ruby 快速排序实现中的最终数组是如何构造的?
【发布时间】:2016-12-13 02:16:43
【问题描述】:

我正在学习一些 Ruby 中的排序算法,并学习了快速排序的这种递归实现:

class Array
  def quicksort
    return [] if empty?

    pivot = delete_at(rand(size))

    left, right = partition(&pivot.method(:>))

    return *left.quicksort, pivot, *right.quicksort
  end
end

array = [5,3,2,18,1,6,4,7,5,9,0]
p array
#=> [5, 3, 2, 18, 1, 6, 4, 7, 5, 9, 0]

p array.quicksort
#=> [0, 1, 2, 3, 4, 5, 5, 6, 7, 9, 18]

我想我基本上明白这里发生了什么。我有这个权利吗?

选择任意枢轴,存储数字并从数组中删除该索引。然后对数组进行分区,将数字> pivot 放入数组left,将数字< pivot 放入rightReturn pivot 并在 leftright 数组中递归调用快速排序(如果其中有任何内容)。

我不明白的是最终数组是如何构造的;我没有看到返回的数字在哪里分配了适当的索引。返回pivot 时会发生这种情况吗?它如何最终出现在正确的索引中?

我认为我的一些困惑来自于对递归缺乏了解。

提前感谢您的帮助。

【问题讨论】:

    标签: arrays ruby algorithm sorting recursion


    【解决方案1】:

    当您使用值列表调用return 时,Ruby 会将列表转换为数组并返回该数组。

    def return_array
      return 1, 2
    end
    return_array
    #=> [1, 2]
    

    这可以与 Array to Arguments Conversion 结合使用,后者使用 splat 运算符“*”将数组转换为元素列表。

    a = [1, 2]
    def add(c, d)
      c + d
    end
    add(*a)
    #=> 3
    

    快速排序方法中的 return 语句可以做到这一点,它返回一个列表

    1. 左侧的splat快速排序结果,即所有小于主元的元素(pivot.method(:>).call(elem),即pivot > elem
    2. 枢轴
    3. 右侧的splat快速排序结果,即所有大于或等于枢轴的元素(! (pivot > elem)

    Ruby 将它们转换为一个数组并返回该数组。

    【讨论】:

    • 啊哈!我知道我哪里出错了。 Left 获得的值小于枢轴!我左右颠倒了。现在完全有道理。枢轴保持它在列表中的位置,它相对于其他所有内容的正确位置,并且左右递归排序,直到所有数字都过滤到正确的位置。该排序列表作为数组返回。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 2011-03-29
    • 2017-02-18
    • 1970-01-01
    相关资源
    最近更新 更多