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

第三回 (2012年10月5日)

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

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

Martin J. Dürst

AGU

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

目次

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

同等な考え方はメモリの量などにも応用可能

漸近的な増加の例

(asymptotic growth)

ステップの数
n (データの個数) 1 10 100 1,000 10,000 100,000 1,000,000
線形探索 (+, []) 2 20 200 2000 20,000 ~199,930 -
2分探索 (-, +, /, []) 5 13~17 25~31 41 53~57 65~69 77~81

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

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

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

 線形探索: 2n; 2分探索: 4 log2n

注意点

O() の意味

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

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

対数の底

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

(参考: logb a = logc a / logc b)

単純化

O(na + nb) ∧a > bO(na)

O(a) ⇒

 

よくあるオーダー

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

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

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

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

多項式の重要性

抽象データ型

(abstract data type, ADT)

スタック

(stack)

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

スタックの公理

つぎの四つの公理でスタックの定義が可能

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

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

公理は実装と使用の間の約束事

キュー

(queue)

具体例
食堂などの待ち行列
IT の例
実行待ちプロセスのキュー
原理
first-in-first-out (FIFO)
Explain the meaning of GIGO: Garbage in, garbage out.

ADT の比較

実装: 3ADTs.rb

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

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

キューの実装

リングバッファ (ring buffer)

線形リスト

(linear list)

辞書

(dictionary)

次回のための準備