スタック

5月 6th, 2008 admin Posted in Ruby, 今日のコード | 2 Comments »

まだまだ続く「アルゴリズムとデータ構造シリーズ」です。今回からスタック&キューについてです。

スタックとは

スタックとは最後に入れたデータが最初に取り出される特徴をもつデータ構造の一つ。
「後入れ先出し」「Last in first out(LIFO)」などと呼ばれる。
スタックではデータを入力することを「積む」「Push」などと表現し、出力させることを「取り出す」「Pop」と表現する。
スタックが空なのにデータを取り出そうとしてしまうことをスタックアンダーフロー、逆にスタックが一杯になっているのにデータを積もうとしてしまうことをスタックオーバーフローと言う。

Rubyの場合は配列にpopとpushメソッドが標準であるため配列をスタックとして簡単に使うことができる。
さらにRubyの場合には配列のサイズも動的に変更できるため、いつも以上に無駄な感じがするので前回作ったリストを使って(まじめに?)スタックを書いた。

コード

RUBY:
  1. #Stack
  2. class Node
  3.   attr_accessor :prev,:next,:data
  4.   def initialize(data)
  5.     @data = data
  6.   end
  7. end
  8.  
  9. class Stack
  10.   def initialize()
  11.     @current_node = Node.new(nil);
  12.     @current_node.prev = nil
  13.   end
  14.  
  15.   def pop
  16.     #スタックのサイズが0ならnil
  17.     if @current_node.prev.nil?
  18.       nil
  19.     else
  20.       @current_node = @current_node.prev
  21.       @current_node.data
  22.     end
  23.   end
  24.  
  25.   def push(x)
  26.     #スタックにデータを積む
  27.     @current_node.data = x
  28.     #次のノードを用意しリンクする
  29.     new_node = Node.new(x)
  30.     @current_node.next = new_node
  31.     new_node.prev = @current_node
  32.    
  33.     #新しいノードをセットする
  34.     @current_node = new_node
  35.   end
  36. end
  37.  
  38. stack = Stack.new()
  39. stack.push(1)
  40. stack.push(2)
  41. stack.push(3)
  42. p stack.pop() # 3 <-最後に入れたのが最初にでてきている
  43. p stack.pop() # 2
  44. p stack.pop() # 1 <-最初に入れたのが最後にでてきている
  45. p stack.pop() # nil <-スタックアンダーフロー

応用

スタックに配列を使い、データの出し入れに配列のpopとpushメソッドを使用した場合と比較しました。
それぞれ1から10000までのデータをpushしてpopするというものです。以下Ruby配列版のコードです。

RUBY:
  1. #Stack
  2. stack = Array.new()
  3.  
  4. 10000.times do |i|
  5.   stack.push(i)
  6. end
  7.  
  8. until stack.pop == nil do
  9. end

私の環境でRuby配列版が4.79秒、リスト版が1.79秒と2倍以上の差が開く結果になりました。
配列のサイズをガンガン広げるより早いんじゃないかと期待したんですが・・・Rubyのコードを読めばわかるのかな?

まとめ

スタックはとても単純で「だからなんなの?」という感じもしなくもないんですが、すごい便利な使い方があったりして驚かされます。
次回はこの応用として、括弧の対応調べとか逆ポーランド電卓にチャレンジしてみます。

※このシリーズは私がRubyでアルゴリズムとデータ構造を基礎から学ぶ記録です。全体の目次はこちらへ。

2 Responses to “スタック”

  1. [...] スタック はてなに追加 MyYahoo!に追加 del.icio.usに追加 livedoorClipに追加 6 Responses to “Rubyでアルゴリズムとデータ構造” [...]

  2. [...] 昨日学んだスタックの応用でHTMLなどの括弧の対応が正しく取れているかどうかを判定するスクリプトを書きました。 "< "と">"が正しい順番で同じ数になっているかどうかを判定します。 [...]