最終更新日:2026年8月28日
fe fe-technology data-structure algorithm
まず結論
スタックとは、最後に入れたデータを最初に取り出すLIFO(後入れ先出し)のデータ構造です。
基本情報技術者試験では、次の対応を押さえます。
- 関数呼出し・戻り番地・ローカル変数 → スタック
- 計算途中の値を保存し、後で取り出して使う → スタック
- 最後に入れたものから取り出す → LIFO
- 最初に入れたものから取り出す → キュー
- 配列の同じ端から追加し、同じ端から取り出す → スタック
- 最終状態から元の値を求める → 命令を後ろから逆向きにたどる
試験では、用語を暗記するよりも、「どこに追加し、どこから取り出しているか」を見ると判断しやすくなります。
スタックとキューの違いを先に整理したい場合は、スタックとキューの違い|LIFOとFIFOを見分ける方法 を確認すると、取り出し順の違いから理解できます。
直感的な説明
スタックは、積み重ねた皿のイメージです。新しい皿は一番上に置き、取り出すときも一番上から取ります。
C ← 最後に置いた皿
B
A
A、B、Cの順に置いたなら、取り出す順番はC、B、Aです。
入れる:A → B → C
出す :C → B → A
この性質を、英語で LIFO(Last In, First Out) といいます。
関数Aから関数Bを呼び、さらに関数Bから関数Cを呼ぶ場合、戻る順番はC、B、Aです。呼び出した順番とは逆に戻るため、スタックが使われます。
計算式でも同じです。ある計算の途中結果をいったん積んでおき、別の計算を終えた後で、最後に積んだ途中結果から取り出して計算を続けられます。
定義・仕組み
スタックの代表的な操作は次の二つです。
| 操作 | 初心者向けの読み替え | 意味 |
|---|---|---|
| push(プッシュ) | データを入れる・追加する | データを一番上に追加する |
| pop(ポップ) | データを取り出す | 一番上のデータを取り出す |
A、B、Cの順にpushした場合、popされる順番はC、B、Aです。
配列と添字でスタックを表す
スタックは、配列と「現在の一番上の位置」を示す変数を使って実装できます。
例えば、配列を A、一番上の位置を示す変数を p とすると、次のような処理を考えられます。
push(x)
p = p + 1
A[p] = x
pop()
x = A[p]
p = p - 1
return x
ここで p はデータそのものではなく、現在の一番上の要素がある位置を管理するための変数です。
push では、p を1増やしてから新しいデータを A[p] に格納します。
pop では、現在の A[p] を取り出してから p を1減らします。
つまり、
追加 :配列の末尾
取出し:配列の末尾
と、同じ側から追加・取出しを行っています。この動きが見えたら、スタックを疑います。
例えば、初期値を p = 0 として、次の順に処理します。
push(A)
push(B)
push(C)
すると、状態は次のようになります。
p = 3
A[3] = C ← 一番上
A[2] = B
A[1] = A
ここで pop() を実行すると、最初に取り出されるのは C です。
pop() → C
p = 2
最後に入れたCが最初に出るため、LIFO=スタックと判断できます。
配列そのものについて復習したい場合は、配列とは?添字でデータを順番に扱う基本構造も確認してみてください。
このテーマは、基本情報技術者試験の「アルゴリズムとプログラミング」やデータ構造と関係が深い内容です。公式情報は、IPA:基本情報技術者試験 から確認できます。
計算途中の値を保存する
加減乗除を組み合わせた計算では、先に求めた途中結果を一時保存し、別の計算が終わった後で取り出して使うことがあります。
例えば、次のような流れです。
途中結果Aを計算する
push(A)
別の途中結果Bを計算する
A = pop()
AとBを使って次の計算を行う
最後に保存した途中結果を最初に使う場面では、LIFOのスタックが適しています。
ただし、スタックは途中にある値を自由に変更したり、好きな位置へ新しい値を挿入したりする構造ではありません。基本操作は、一番上への追加と一番上からの取出しです。
関数呼出しとコールスタック
関数や手続を呼び出すときは、呼出し元へ戻るための情報を一時保存します。
- 戻り番地
- 引数
- ローカル変数
- 処理途中の値
これらを呼出しごとに積み重ねる領域をコールスタックと呼びます。関数が終了すると、その関数の情報を取り出して呼出し元へ戻ります。
再帰呼出しが深すぎるとスタック領域を使い切ることがあります。これがスタックオーバーフローです。
科目Aでどう出る?
次のキーワードが出たらスタックを選びます。
- 後入れ先出し
- LIFO
- pushとpop
- 配列の同じ端で追加と取出しを行う
- 計算途中の値を一時保存する
- 保存した途中結果を後で取り出して計算する
- 関数呼出し
- 戻り番地
- ローカル変数
- 最後に呼び出した処理から先に戻る
| 説明 | データ構造 |
|---|---|
| 配列の末尾に追加し、末尾から取り出す | スタック |
| 計算途中の値を保存し、後で取り出して利用する | スタック |
| 関数呼出し時の戻り番地を保存する | スタック |
| 格納した順番に取り出す | キュー |
| 到着順や受付順で処理する | キュー |
| 値の大小関係を使って検索する | 2分探索木 |
| 前後の要素を双方向にたどる | 双方向連結リスト |
選択肢では、一時保存という言葉だけで判断せず、どの順番で取り出すかを確認します。
同じ端から追加・取出し
→ スタック
後ろから追加・前から取出し
→ キュー
最終状態から逆向きにたどる問題
科目Aでは、pushとpopを実行した後のスタックだけが示され、最初にpushした値などを逆算する問題もあります。
前から追ってもpushする値が分からない場合は、命令列を最後から逆向きにたどります。
| 元の命令 | 通常の操作 | 逆向きに戻す操作 |
|---|---|---|
| push | 一番上に値を追加する | 一番上の値を取り除く |
| pop | 一番上の値を取り出す | 取り出された値を積み直す |
例えば、実行後のスタックが次の状態だとします。
上
C
B
A
下
最後の命令がpushなら、そのpushで追加された値は現在一番上のCです。逆向きに戻すときは、Cを取り除きます。
上
B
A
下
最後の命令がpopなら、元の処理では何らかの値が取り出されています。逆向きでは、その値を一番上に積み直します。
上
?
C
B
A
下
取り出された値が分からない場合は、無理に決めずに?として置きます。後の命令を逆向きにたどることで、その?が取り除かれたり、必要な位置関係だけが分かったりします。
試験中は、次のように判断します。
最初から値が分かる
→ push・popを前から実行する
途中の値が不明で、最終状態が分かる
→ 命令を後ろから逆向きにたどる
逆向きに追うときも、操作できる場所は常にスタックの一番上です。
科目Bでどう使う?
科目Bでは、pushとpopのたびにスタックの状態を書き換えて追います。
push(A)
push(B)
pop() → B
push(C)
pop() → C
pop() → A
計算処理でも、途中結果がどの順番で積まれ、どの値がpopされるかを一つずつ追います。
push(8) スタック:[8]
push(3) スタック:[8, 3]
pop() 取り出す値:3、スタック:[8]
push(5) スタック:[8, 5]
pop() 取り出す値:5、スタック:[8]
配列で実装された処理を読む
科目Bでは、push や pop という名前が使われず、配列と添字だけでスタックを表すことがあります。
例えば、
p = p + 1
A[p] = x
という処理なら、p を進めて配列の末尾へ追加しています。
一方、
x = A[p]
p = p - 1
なら、現在の末尾から取り出して、p を一つ戻しています。
このときは、処理名ではなく、
追加する場所と取り出す場所が同じか
を確認します。
試験中は、次のような小さな表を書くと安全です。
| 手順 | p | 操作 | 取り出した値 |
|---|---|---|---|
| 初期 | 0 | - | - |
| 1 | 1 | Aを追加 | - |
| 2 | 2 | Bを追加 | - |
| 3 | 3 | Cを追加 | - |
| 4 | 2 | Cを取り出す | C |
特に確認するのは次の3点です。
pが増えるのは格納の前か後か- どの
A[p]を読み書きしているか - 取出し後に
pがどこを指すか
頭の中だけで追わず、処理ごとに「p」「配列の中身」「取り出した値」をメモするとミスを減らせます。
よくある誤解・混同
一時保存ならキューでもよい
重要なのは保存できるかではなく、取り出す順番です。最後に保存した途中結果から先に使う場合や、最後に呼び出した関数から先に戻る場合はスタックを使います。
格納した順番に取り出すのがスタック
これはキューです。スタックは格納した順番とは逆に、最後に格納した値から取り出します。
配列を使っていればスタックである
これは誤りです。
配列はデータを置くための入れ物であり、スタックかどうかは追加と取出しの方法で決まります。
末尾に追加・末尾から取出し
→ スタック
末尾に追加・先頭から取出し
→ キュー
pは必ず「要素数」を表す
p の意味は問題の処理によって変わります。
要素数として使う場合もあれば、現在のトップ位置を示す場合もあります。
そのため、p という変数名だけで判断せず、初期値と、代入・増減の順番をそのまま追うことが大切です。
スタックの途中にある値を直接変更できる
単純なスタックで直接操作できるのは一番上の値です。途中の値だけを変更したり、途中へ新しい値を挿入したりする処理には向きません。
戻り番地だけを保存する
戻り番地だけでなく、引数、ローカル変数、処理途中の値なども保存します。
pushとpopを逆に覚える
pushは「データを入れる」、popは「データを取り出す」と日本語へ置き換えると整理しやすくなります。popした値はスタックから取り除かれます。
逆向きでもpushは値を積む
これは誤りです。命令列を逆向きに戻すときは、元のpushによって追加された一番上の値を取り除きます。
通常のpush
→ 一番上に追加する
pushを逆向きに戻す
→ 一番上を取り除く
同様に、元のpopを逆向きに戻すときは、取り出された値を一番上へ積み直します。
確認問題(基本情報技術者試験対策)
複数の計算を行う処理で、先に求めた途中結果を一時保存し、別の計算を行った後、最後に保存した途中結果から取り出して計算を続ける。この処理に適したデータ構造はどれか。
- ア. キュー
- イ. スタック
- ウ. 2分探索木
- エ. 双方向連結リスト
▶ クリックして答えと解説を見る(ここを開く)
正解:イ
- キューはFIFOで、最初に保存した値から取り出します。
- スタックはLIFOで、最後に保存した途中結果から取り出す処理に適しています。
- 2分探索木は値の大小関係を利用した検索に使います。
- 双方向連結リストは前後の要素をたどったり、要素を挿入・削除したりする構造です。
まとめ(試験直前用)
- スタックはLIFO(後入れ先出し)
- push(プッシュ)は「データを入れる」、pop(ポップ)は「データを取り出す」
- 同じ端から追加・取出しをしていたらスタックを疑う
- 配列で実装された場合は、トップ位置を示す変数の増減を追う
- 科目Bでは「p」「配列の中身」「取り出した値」を順番にメモする
- 科目Aでは最終状態から命令を逆向きにたどる問題もある
- 逆向きでは、pushは一番上を取り除き、popは値を積み直す
- 関数呼出し時の戻り番地やローカル変数を保存する
- キューはFIFO(先入れ先出し)
- 再帰が深すぎるとスタックオーバーフローが起こる
スタックとキューを取り出し順でまとめて復習したい場合は、スタックとキューの違い に戻ると整理しやすくなります。