大きな画面での利用をおすすめします — アニメーションと操作がより快適になります。
入力

スタック

スタックは後入れ先出し(LIFO)です。push は頂上に要素を置き、pop は最後に置いた要素を取り出します。同じ端だけを操作し、中間の移動や走査はしません。この Python リスト実装では、両操作の償却時間は O(1) です。

重ねた皿の上に置き、上から取ると考えてください。この制約は、関数呼び出し、取り消し履歴、括弧の対応、深さ優先探索など、逆順に戻る処理に適しています。

スタックの仕組み

コードは Python リスト data と容量 max で有界スタックを作ります。push(val) は最初に len(self.data) >= self.max を検査します。満杯なら Stack Overflow を送出し、そうでなければ末尾に val を追加します。pop() は空なら Stack Underflow を送出し、空でなければ末尾を削除して返します。

頂上はリストの最後のインデックスです。append と list.pop() はこの端で動き、その下の要素を走査しません。

容量制限はこの実装の規則で、LIFO 自体の条件ではありません。組み込みでは有界スタックを使いますが、通常の Python リストは利用可能なメモリに応じて成長します。スライダーの 3–10 は画面の表示制限です。

操作をステップで追う

既定は空のスタック、容量 8 です。追加と取り出しのボタンで実行します。

  1. push(3):0 < 8 で検査を通過し、[3]。頂上のインデックスは 0。
  2. push(7):[3, 7]。古い頂上の上に新しい要素を置く。
  3. push(1):[3, 7, 1]。
  4. pop():最後に入れた 1 を返し、[3, 7] が残る。
  5. pop():7 を返し、[3] が残る。
  6. push(9):[3, 9]。以前 7 が占めた位置を再利用する。
  7. pop() を二回:9、3 の順に返し、空になる。さらに一回でアンダーフロー。

容量 8 に九個目を入れる例も試してください。追加前にオーバーフローとなり、失敗した操作は状態を変えません。

画面では上だけが開いた容器を使い、要素は上から入り、上へ出ます。ヘッダーの size と頂上の値が更新され、空なら頂上の値を隠します。古い値を表示し続けないためです。上の手順が状態の全記録です。

時間・空間計算量

操作時間空間
push償却 O(1)要素ごとに O(1)
pop償却 O(1)—
peekO(1)—
全体の保存領域—O(n)

頂上だけにアクセスするインターフェースと、リスト末尾の実装がこの費用を支えます。規則と保存方法を合わせて評価してください。

境界ケース

  • 満杯への追加:オーバーフロー。状態は変わらない。
  • 空からの取り出し:アンダーフロー。空を調べるか例外を処理する。
  • 一要素:追加して取り出すと同じ値が戻り、サイズは 0 → 1 → 0。
  • 重複値:使用できる。集合ではなく順序を保存する構造。

よくある間違い

  • pop と peek の混同。 pop は削除します。見るだけなら空を確認して data[-1] を読みます。
  • 端を混ぜる。 後ろから入れ、前から出すとキューになります。
  • 空の検査を省く。 Python の空リストの pop() は例外、JavaScript 配列は undefined を返します。API に応じて処理してください。
  • 中間への添字アクセスを公開する。 data[k] を自由に読むなら LIFO に制限したインターフェースではありません。リストや deque を検討します。
  • コールスタックを見落とす。 関数呼び出しでフレームを積み、復帰で取り出します。再帰のスタックオーバーフローは、実行時のコールスタックの枯渇です。