http://www.sw.it.aoyama.ac.jp/2013/DA/lecture5.html
© 2009-13 Martin J. Dürst 青山学院大学
次の関数をオーダの順にならべ、理由を付けなさい。
O(n2), O(n!), O(n log log n), O(n log n), O(20n)
[都合により削除]
順位キュー (priority queue) という ADT を実装しなさい
(Ruby でも他言語でもよい)
順位キューは各要素ごとに優先度 (整数など) が付く。一番簡単な場合にデータ項目は優先度だけ。優先度の高いものが先にキューから出る。実装は配列でも連結リストでもよい。
正解例: 5prioQ.rb
(priority queue, 優先順位キュー、優先順位付き待ち行列)
insert (add,...): 項目の追加、getNext/delMax/...: 最優先項目の返しと削除
実装 | 配列 (常順) | 配列 (探索) | 連結リスト (常順) | 連結リスト (探索) |
新規作成 | O(1) | O(1) | O(1) | O(1) |
項目追加 | O(n) | O(1) | O(n) | O(1) |
最優先項目 | O(1) | O(n) | O(1) | O(n) |
項目削除 | O(1) | O(n) | O(1) | O(n) |
empty? |
O(1) | O(1) | O(1) | O(1) |
長さ | O(1) | O(1) | O(n) | O(n) |
実装によって操作の計算量が違うが、必ずどこかで O(n) の計算量になる
改善は可能でしょうか
木構造に基づく定義:
別の定義 (Knuth):
(heap)
⇒ ルートは常に一番優先
各操作の実現:
(英語: invariant)
ある場所で、優先度が高かすぎる可能性の場合:
heapify_up
親と比較、必要であれば交換、交換されたら親で続く
ある場所で、優先度が低くすぎる可能性の場合:
heapify_down
子と比較、必要であれば優先度の高い子と交換、交換された子で続く
実装: 5heap.rb
実装 | Heap (Array による実装) |
新規作成 | O(1) |
項目追加 | O(log n) |
最優先項目 | O(1) |
項目削除 | O(log n) |
empty? |
O(1) |
長さ | O(1) |
(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.add 3 => #<Heap:0x2833d60 @array=[nil, 3], @size=1> irb(main):004:0> h.add(5).add(7) => #<Heap:0x2833d60 @array=[nil, 7, 3, 5], @size=3> ...