簡易 PQueue
バイナリヒープの優先度付きキュー
使い方
pq = PQueue.new %w/1 12 123 abcd abc/.each do |w| pq.enq(w,w.size) # 優先度を指定して追加する。#enq(value, priority) end puts pq.deq until pq.empty? # #deqでpriorityの小さいもの取り出せる
1 12 abc 123 abcd
class PQueue Node = Struct.new(:value, :priority) def initialize @heap = [] end def size; @heap.size; end def empty?; @heap.empty?; end def peek; empty? ? nil : @heap[0].value; end def enq(value, priority) el = Node.new(value, priority) j = @heap.size @heap << nil while j > 0 up = (j - 1) / 2 break if @heap[up].priority < el.priority @heap[j] = @heap[up] j = up end @heap[j] = el self end def deq return nil if empty? return @heap.shift.value if size == 1 ret = @heap[0] @heap[0] = nil el = @heap.pop i = 0 while 2 * i + 1 < @heap.size l = 2 * i + 1 r = 2 * i + 2 j = (r == @heap.size || @heap[l].priority <= @heap[r].priority) ? l : r break if el.priority <= @heap[j].priority @heap[i] = @heap[j] i = j end @heap[i] = el return ret.value end end