データ構造とアルゴリズム

第四回 (2009年10月 23日)

ヒープとヒープソート

http://www.sw.it.aoyama.ac.jp/2009/DA/lecture4.html

Martin J. Dürst

AGU

© 2008-09 Martin J. Dürst 青山学院大学

目次

前回のまとめ

前回の宿題 (1)

次の関数をオーダの順にならべ、理由を付けなさい。

O(n2), O(n!), O(n log log n), O(n log n), O(20n)

正解: O(n log log n), O(n log n), O(n2), O(20n), O(n!)

f(n) g(n) n0 c
n log log n n log n 2 1
n log n n2 2 1
n2 20n 1 1
20n n! 52 1
20n n! 20 2020/20!

ヒント: Ruby は Bignum がある為に馬鹿でかい数字の計算に使いやすい

前回の宿題 (2)

Priority Queue という ADT を実装しなさい (Ruby でも他言語でもよい)

Priority Queue は各要素ごとに優先度 (整数など) が付く。優先度の高いものが先にキューから出る。実装は配列でも連結リストでもよい。

順位キュー

(priority queue, 優先順位キュー、優先順位付き待ち行列)

IT の例
プロセス管理など
操作
作成 (new, init)、空かどうかのテスト

insert (add,...): 項目の追加、getNext/delMax/...: 最優先項目の返しと削除

findMax/peekAtNext/...: 最優先項目を返すだけ

単純な実装

各操作の計算量
実装 Array (常順) Array (探索) LinearList (常順) LinearList (探索)
新規作成 O(n) O(n) 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)

完全二分木

木構造空の定義:

別の定義 (Knuth):

ヒープ

(heap)

⇒ ルートは常に一番優先

各操作の実現:

普遍条件

(英語: invariant)

ヒープの普遍条件の修復

現在の場所にして優先度が高い可能性の場合: heapify_up
親と比較、必要であれば交換、交換されたら親で続く

現在の場所にして優先度が低い可能性の場合: heapify_down
子と比較、必要であれば優先度の高い子と交換、交換されたら子で続く

実装: 4heap.rb

ヒープによる順位キューの実装

各操作の計算量
実装 Heap (Array による実装)
新規作成 O(n)
項目追加 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 '4heap'
=> 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>
 ...

その他のヒープ

今回のまとめ

次回のための準備