http://www.sw.it.aoyama.ac.jp/2014/DA/lecture5.html
© 2009-14 Martin J. Dürst 青山学院大学
来年度、金曜日一限から木曜日一限への方向が検討中
次の関数をオーダの順にならべ、理由を付けなさい。
O(n2), O(n!), O(n log log n), O(n log n), O(20n)
[都合により削除]
順位キュー (priority queue) という ADT を実装しなさい
(Ruby でも他言語でもよい)
[都合により削除]
(priority queue, 優先順位キュー、優先順位付き待ち行列)
insert (add,...): 項目の追加、getNext/delMax/...: 最優先項目の返しと削除
実装 | 配列 (整列済み) | 配列 (探索) | 連結リスト (整列済み) | 連結リスト (探索) |
insert |
O(n) | O(1) | O(n) | O(1) |
getNext |
O(1) | O(n) | O(1) | O(n) |
findMax |
O(1) | O(n) | O(1) | O(n) |
実装によって操作の計算量が違うが、必ずどちらかの操作が O(n)
改善は可能でしょうか
(complete binary tree)
木構造に基づく定義:
(heap)
⇒ ルートは常に一番優先
各操作の実現:
(英語: invariant)
ある場所で、優先度が高かすぎる可能性の場合:
heapify_up
親と比較、必要であれば交換、交換されたら親で続く
ある場所で、優先度が低くすぎる可能性の場合:
heapify_down
子と比較、必要であれば優先度の高い子と交換、交換された子で続く
実装: 5heap.rb
実装 | Heap (Array による実装) |
insert |
O(log n) |
findMax |
O(1) |
getNext |
O(log n) |
(heap sort)
irb
の使い方irb
: Interactive Ruby, Ruby
用のコマンドプロンプト
使用例:
C:\Algorithms>irb irb(main):001:0> require './5heap' => true irb(main):002:0> h = Heap.new => #<Heap:0x2833d60 @array=[nil], @size=0> irb(main):003:0> h.insert 3 => #<Heap:0x2833d60 @array=[nil, 3], @size=1> irb(main):004:0> h.insert(5).insert(7) => #<Heap:0x2833d60 @array=[nil, 7, 3, 5], @size=3> ...
heapify_all
は O(n/2 · log
n) で O(n log n)
に見えるが、細かく分析すると違う結果になる