argius note

プログラミング関連

練習:クイックソート (続き)

頭の中の材料だけでやろうとしたんだけど...だめだ、理屈はわかっているんだけど、答えが合わない!
というわけで、アルゴリズム事典に頼ってしまいました。ちょっと情けないですが、そこから自分流キレイ風にアレンジするのに頑張りました。
同時に、まだ使い慣れないモジュールの練習も兼ねて。インスタンスにモジュール「装着」してる感覚です。多重代入の良い例と悪い例、配列の初期化なども練習のうち。

module Sort
  module QuickSort
    def sort () self.clone.sort! end
    def sort! () execute(self, 0, self.size - 1) end
    def execute (a, f, t)
      x = a[(f + t) / 2]
      i, j = f, t # 多重代入にする必要がない
      while true
        i += 1 while a[i] < x
        j -= 1 while a[j] > x
        break unless i < j
        a[i], a[j] = a[j], a[i] # 交換には適している
        i += 1
        j -= 1
      end
      execute(a, f, i - 1) if (f < i - 1)
      execute(a, j + 1, t) if (j + 1 < t)
      return a
    end
    private :execute
  end
end

o = Array.new(16) do |i| rand(1000) end
a = o.clone
b = o.clone.extend Sort::QuickSort
p a.sort!
p b.sort!
puts a == b

ランダムだから毎回結果は異なりますが、最後がtrueならOKってことで。

[352, 771, 576, 933, 388, 746, 898, 894, 372, 763, 8, 364, 584, 498, 579, 743]
[8, 352, 364, 372, 388, 498, 576, 579, 584, 743, 746, 763, 771, 894, 898, 933]
[8, 352, 364, 372, 388, 498, 576, 579, 584, 743, 746, 763, 771, 894, 898, 933]
true