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

第三回 (2010年10月8日)

抽象データ型とデータ構造、スタック、キューなど

http://www.sw.it.aoyama.ac.jp/2010/DA/lecture3.html

Martin J. Dürst

AGU

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

目次

計算量の比較: 具体から抽象へ

漸近的な増加の例

(asymptotic growth)

ステップの数
n (データの個数) 1 10 100 1,000 10,000 100,000 1,000,000
線形探索 7 52 502 5,002 50,002 500,002
2分探索 11 35 59 83 115 139 163

ステップの数を式で表すとどうなる

線形探索: 5n+2; 2分探索: 8 ⌈log2(n+1)⌉ + 3

データの個数が多くなると式のどの項が重くなる

 線形探索: 5n; 2分探索: 8 log2n

関数のオーダー

注意点

=の意味

f (n) = O(g (n)) と書くが、

f (n) ∈ O(g (n)) の方が意味に近い

対数の底

O(log2 n) と O(log10 n) はどう違うか

単純化

O(na + nb) ⇒O(na) [a > b の前提で]

O(a) ⇒

よくあるオーダー

O(n): データの大きさに比例、全てのデータをチェック

O(log n), O(n log n): 二分探索など、データを小分けして処理する場合

O(n2), O(n3): データの二つ、三つの組み合わせを考える場合

O(2n): データの全ての部分集合を検討する場合など

多項式の重要性

抽象データ型

(abstract data type, ADT)

スタック

(stack)

具体例
食堂の食膳の山
IT の例
プログラムの関数呼び出しのためのスタック
原理
last-in-first-out (LIFO)
主なメソッド
新規作成 (new), 追加 (push), 削除 (pop)
その他のメソッド
空かどうかのチェック (empty?)、長さ (size)、最上のデータ項目をのぞく (top)

スタックの公理

つぎの六つの公理からスタックの全ての性質を導くことが可能

  1. Stack.new.empty? ↔ true
  2. s.push(e).empty? ↔ false
  3. Stack.new.size ↔ 0
  4. s.push(e).size ↔ s.size + 1
  5. s.push(e).top ↔ e
  6. s.push(e).pop ↔ s (pop はデータではなく、スタックを返す)

(s が任意のスタック、e が任意のデータ項目)

キュー

(queue)

具体例
食堂などの待ち行列
IT の例
実行待ちプロセスのキュー
原理
first-in-first-out (FIFO)

ADT の比較

実装: 3ADTs.rb

ADT スタック キュー
実装 Array LinkedList Array LinkedList
新規作成 O(n) O(1) O(n) O(1)
項目追加 O(1) O(1) O(1) 又は O(n) O(n) 又は O(1)
項目削除 O(1) O(1) O(n) 又は O(1) O(1) 又は O(n)
empty? O(1) O(1) O(1) O(1)
長さ O(1) O(n) O(1) O(n)

演習: 3ADTs.rb にあるクラスを使うプログラムを作成しなさい。

キューの実装

リングバッファ (ring buffer)

双方向連結リスト

線形リスト

(linear list)

辞書

(dictionary)

次回のための準備