ヒープのsiftdownリファクタリング
MyHeapのsiftdownでコードの重複と分岐の分かりづらさが気になったので書き換えてみた。
def siftdown(n) if n * 2 > @n then return elsif n * 2 == @n then if @q[n] > @q[n * 2] then @q[n], @q[n * 2] = @q[n * 2], @q[n] end elsif n * 2 + 1 <= @n then left = n * 2 right = n * 2 + 1 if (@q[left] < @q[right]) && (@q[n] > @q[left]) then @q[n], @q[left] = @q[left], @q[n] siftdown(left) end if (@q[right] < @q[left]) && (@q[n] > @q[right]) then @q[n], @q[right] = @q[right], @q[n] siftdown(right) end end end
def siftdown(n) left = n * 2 right = left + 1 case when @n < left then return when @n == left then if @q[n] > @q[left] then @q[n], @q[left] = @q[left], @q[n] end when @n >= right then [left, right].permutation.each do |a, b| if (@q[a] < @q[b]) && (@q[n] > @q[a]) then @q[n], @q[a] = @q[a], @q[n] siftdown(a) end end end end
すっきりしたとは言え、[left, right].permutationのところが、かなり意味が分かりづらくなった気がする。かといって、[ [left, right], [right, left] ]はないだろう……。
それと、a, b = b, aみたいな多重代入って長くなると見にくくなって、swap(a, b)みたいな書き方ができたほうがすっきりするようにも思える。