メインコンテンツへスキップ
見出し画像

【基本情報】スタック・キューを完全理解|科目Bのデータ構造対策

    「スタックとキュー、毎回どっちがFIFOか分からなくなる……😇」

    「LIFOとFIFOは覚えたけど、問題になると解けない」

    「科目Bの擬似言語で出てくると一気に難しく感じる」

    基本情報技術者試験の科目Bを勉強していると、避けて通れないのが、

    スタック(Stack)

    と

    キュー(Queue)

    です。

    名前だけ見ると難しそうですが、基本的な考え方はかなりシンプル。

    まずはこれだけ覚えてください👇

    スタック=後入れ先出し(LIFO)

    キュー=先入れ先出し(FIFO)


    ただし、試験では単純にLIFO・FIFOを答えるだけではありません。

    実際には、

    • データを追加したらどうなる?

    • データを取り出したら何が出る?

    • 擬似言語を実行した後の状態は?

    • どんな場面でスタック・キューを使う?

    といった形で問われます。

    この記事では、

    基本イメージ → LIFO/FIFO → 操作方法 → 擬似言語 → トレース → 練習問題

    の順番で解説します。

    スタックとキューを「暗記」ではなく、動きをイメージして解ける状態を目指しましょう🔥

    ⸻

    1.そもそもデータ構造とは?

    スタックとキューを理解する前に、

    データ構造

    について簡単に確認します。

    データ構造とは、

    データをどのような形で管理するか

    を表したものです。

    例えば、同じA・B・Cというデータでも、

    A
    B
    C

    という順番で保存するだけではなく、

    どこから追加するのか

    どこから取り出すのか


    によってデータの扱い方が変わります。

    代表的なデータ構造には、

    • 配列

    • リスト

    • スタック

    • キュー

    • 木構造

    などがあります。

    その中でも、科目Bを勉強するうえで最初に押さえておきたいのが、

    スタックとキュー

    です。

    ⸻

    2.まずは違いを一発で整理

    最初に全体像を確認しましょう。

    画像

    ここはそのまま覚えてOKです。

    スタック
    最後に入れたものから取り出す

    キュー
    最初に入れたものから取り出す

    この違いがすべての基本になります。

    ⸻

    3.スタックとは?

    スタック(Stack)は、

    最後に入れたデータを最初に取り出す

    データ構造です。

    これを、

    LIFO

    といいます。

    LIFOは、

    Last In, First Out

    の略です。

    日本語では、

    後入れ先出し

    と覚えます。

    ⸻

    4.スタックは「積み重ねた皿」で考える

    スタックを理解するなら、

    お皿を積み重ねる場面

    をイメージすると分かりやすいです。

    例えば、

    A
    ↓
    B
    ↓
    C

    の順番でデータを入れたとします。

    スタックの状態は、

    画像

    となります。

    では、ここから1つ取り出すと?

    一番上にある、

    C

    が取り出されます。

    つまり、

    入れた順番
    A → B → C

    取り出す順番
    C → B → A

    です。

    ⸻

    5.LIFOを覚える

    スタックでは、

    LIFO

    が重要です。

    Last In
    ↓
    最後に入れたものが
    First Out
    ↓
    最初に出る

    なので、

    Last In, First Out

    です。

    例えば、

    A
    ↓
    B
    ↓
    C

    の順番で入れたら、

    C
    ↓
    B
    ↓
    A

    の順番で取り出します。

    ⸻

    6.スタックへの追加「push」

    スタックにデータを追加する操作を、

    push

    と呼ぶことがあります。

    例えば最初に、

    空(何も入っていない状態)

    だったとします。

    ここで、

    push(A)

    を実行すると、

    画像

    次に、

    push(B)

    なら、

    画像

    さらに、

    push(C)

    なら、

    画像

    です。

    push=スタックへ追加

    と覚えておきましょう。

    ⸻

    7.スタックから取り出す「pop」

    スタックからデータを取り出す操作を、

    pop

    と呼ぶことがあります。

    先ほどの、

    画像

    という状態で、

    pop()

    を実行すると、

    C

    が取り出されます。

    残るのは、

    画像

    です。

    もう一度、

    pop()すると、

    B

    が取り出されます。

    ⸻

    8.pushとpopをセットで覚える

    スタックでは、

    画像

    と覚えておくと分かりやすいです。

    そして重要なのは、

    popでは最後にpushしたデータから取り出される

    こと。

    ここまで理解できれば、スタックの基本はOKです。

    ⸻

    9.スタックを実際にトレースしてみる

    次の操作を考えてみましょう。

    push(10)
    push(20)
    push(30)
    pop()

    順番に追います。

    最初に、

    push(10)

    なので、

    [10]

    次に、

    push(20)

    で、

    [10, 20]

    次に、

    push(30)

    で、

    [10, 20, 30]

    そして、

    pop()

    すると、最後に追加した、

    30

    が取り出されます。

    したがって残るのは、

    [10, 20]

    です。

    ⸻

    10.もう少し複雑なスタック問題

    次の操作を考えます。

    push(A)
    push(B)
    pop()
    push(C)
    push(D)
    pop()

    順番に追いましょう。

    画像

    したがって、最後に残っているのは、

    AとC

    です。

    popで取り出された順番は、

    B → D

    となります。

    ⸻

    11.スタックはどんな場面で使われる?

    スタックは、実際のコンピュータでもさまざまな場面で使われます。

    代表例として、

    • 関数呼出し

    • 再帰処理

    • 式の評価

    • 戻る処理

    • 深さ優先探索

    などがあります。

    例えば、

    「直前の状態へ戻る」

    ような処理は、最後の状態から順番に取り出すスタックと相性がいいです。

    ⸻

    12.キューとは?

    次は、

    キュー(Queue)

    です。

    キューは、

    最初に入れたデータを最初に取り出す

    データ構造です。

    これを、

    FIFO

    といいます。

    FIFOは、

    First In, First Out

    の略です。

    日本語では、

    先入れ先出し

    です。

    ⸻

    13.キューは「レジの行列」で考える

    キューを理解するなら、

    レジに並ぶ行列

    をイメージすると簡単です。

    例えば、

    A → B → C

    という順番で並んだとします。

    一番最初に来たのは、

    A

    です。

    したがって、一番最初に処理されるのも、

    A

    です。

    その次が、

    B

    最後が、

    C

    となります。

    つまり、

    入れた順番
    A → B → C

    取り出す順番
    A → B → C

    です。

    ⸻

    14.FIFOを覚える

    キューでは、

    FIFO

    が重要です。

    First In
    ↓
    最初に入れたものが

    First Out
    ↓
    最初に出る

    つまり、

    First In, First Out

    です。

    スタックとは逆なので、セットで覚えましょう。

    ⸻

    15.キューへの追加「enqueue」

    キューへデータを追加する操作を、

    enqueue(エンキュー)

    と呼びます。

    例えば、

    enqueue(A)

    なら、

    [A]

    次に、

    enqueue(B)

    なら、

    [A, B]

    さらに、

    enqueue(C)

    なら、

    [A, B, C]

    です。

    後から来たデータは、

    列の後ろ

    へ追加されます。

    ⸻

    16.キューから取り出す「dequeue」

    キューからデータを取り出す操作を、

    dequeue(デキュー)

    と呼びます。

    例えば、

    [A, B, C]

    という状態で、

    dequeue()

    すると、

    A

    が取り出されます。

    残るのは、

    [B, C]

    です。

    もう一度、

    dequeue()

    すると、

    B

    が取り出されます。

    残るのは、

    [C]

    です。

    ⸻

    17.enqueueとdequeueをセットで覚える

    キューでは、

    画像

    と覚えます。

    重要なのは、

    追加する場所と取り出す場所が違う

    ことです。

    画像

    イメージとしては、

    後ろから並んで、前から出ていく

    です。

    ⸻

    18.キューをトレースしてみる

    次の操作を考えます。

    enqueue(10)
    enqueue(20)
    enqueue(30)
    dequeue()

    順番に追います。

    enqueue(10)
    [10]

    ↓

    enqueue(20)
    [10, 20]

    ↓

    enqueue(30)
    [10, 20, 30]

    ↓

    dequeue()

    最初に入った、

    10

    が取り出されます。

    残るのは、

    [20, 30]

    です。

    ⸻

    19.もう少し複雑なキュー問題

    次の操作を考えます。

    enqueue(A)
    enqueue(B)
    dequeue()
    enqueue(C)
    enqueue(D)
    dequeue()

    順番に追います。

    画像

    最後に残るのは、

    CとD

    です。

    取り出された順番は、

    A → B

    となります。

    ⸻

    20.スタックとキューを並べて比較

    ここまでの内容を整理します。

    画像

    ここは科目B対策として、すぐ説明できるようにしておきたいところです。

    ⸻

    21.一番簡単な見分け方

    迷ったら、

    「A→B→Cの順番で入れたら、最初に何が出る?」

    と考えてください。

    スタック

    入れる
    A → B → C

    取り出す
    C → B → A

    なので、

    最初にC

    です。

    キュー

    入れる
    A → B → C

    取り出す
    A → B → C

    なので、

    最初にA

    です。

    これだけでもかなり見分けやすくなります。

    ⸻

    22.よくある間違い① LIFOとFIFOを逆にする

    最も多いのが、

    LIFOとFIFOがごちゃごちゃになる

    ことです。

    おすすめの覚え方は、

    LIFO
    Last=最後
    最後に入れたものが先。
    → スタック

    FIFO
    First=最初
    最初に入れたものが先。
    → キュー

    頭文字だけでなく、英語の意味まで理解しておくと忘れにくくなります。

    ⸻

    23.よくある間違い② pushした順番だけを見る

    例えば、

    push(A)
    push(B)
    push(C)

    とあったとします。

    ここで、

    A → B → C

    だから最初にAが出る、と考えてはいけません。

    スタックは、

    LIFO

    です。

    したがって、

    pop()

    すると、

    C

    が出ます。

    操作の順番ではなく、

    データ構造のルール

    を確認しましょう。

    ⸻

    24.よくある間違い③ popとdequeue後の状態を更新しない

    例えばスタックが、

    [A, B, C]

    の状態で、

    pop()

    したら、

    Cが取り出されるだけではありません。

    その後の状態は、

    [A, B]

    になります。

    次の処理は、

    更新後の状態

    から考えます。

    これは擬似言語のトレースと同じです。

    ⸻

    25.よくある間違い④ 頭の中だけで追う

    操作が増えてくると、

    push
    push
    pop
    push
    pop
    push

    のようになります。

    これを頭の中だけで追うと、かなりミスしやすいです。

    おすすめは、

    1操作ごとに状態を書く

    こと。

    例えば、

    画像

    という形です。

    科目Bでは、

    トレース表を作る癖

    をつけておくとかなり強いです。

    ⸻

    26.擬似言語とスタック

    ここから少し科目Bらしい問題を見てみます。

    例えば、

    push(1)
    push(2)
    push(3)

    x ← pop()
    y ← pop()

    とします。

    最初の状態は、

    画像

    です。

    まず、

    x ← pop()

    なので、

    x = 3

    次に、

    y ← pop()

    なので、

    y = 2

    です。

    最後にスタックへ残るのは、

    1

    です。

    ⸻

    27.擬似言語とキュー

    次は、

    enqueue(1)
    enqueue(2)
    enqueue(3)

    x ← dequeue()
    y ← dequeue()

    とします。

    キューの状態は、

    [1, 2, 3]

    です。

    最初に、

    x ← dequeue()

    なので、

    x = 1

    次に、

    y ← dequeue()

    なので、

    y = 2

    です。

    最後に残るのは、

    3

    です。

    ⸻

    28.同じデータでも結果が変わる

    ここが重要です。

    同じ、

    1
    2
    3

    を順番に入れても、

    スタック
    3 → 2 → 1

    キュー
    1 → 2 → 3

    と、取り出す順番が変わります。

    つまり試験では、

    「何を入れたか」だけではなく、「どのデータ構造を使っているか」

    を見る必要があります。

    ⸻

    29.スタックを使って順番を逆にする

    スタックの特徴を利用すると、

    データの順番を逆転

    できます。

    例えば、

    A → B → C

    を順番にpushします。

    すると、

    画像

    です。

    ここから全部popすると、

    C → B → A

    になります。

    つまり、

    入力順を逆にして取り出せる

    わけです。

    ⸻

    30.キューは順番を維持しやすい

    キューでは、

    A → B → C

    と入れたら、

    A → B → C

    と取り出します。

    そのため、

    到着順に処理したい場面

    と相性がいいです。

    例えば、

    • 処理待ちタスク

    • 印刷待ち

    • メッセージ処理

    • 各種リクエストの待ち行列

    などの考え方につながります。

    ⸻

    31.循環キューとは?

    少し発展です。

    キューを配列で実装すると、

    データを取り出すたびに前方に空き領域ができます。

    そこで考えられるのが、

    循環キュー

    です。

    配列の最後まで到達したら、

    先頭へ戻って空いている場所を再利用する

    イメージです。

    画像

    配列を円のように扱うため、

    リングバッファ

    という考え方にもつながります。

    ⸻

    32.循環キューではfrontとrearを意識

    キューでは、

    front

    と、

    rear

    という言葉が使われることがあります。

    ざっくり言えば、

    front
    取り出す側

    rear
    追加する側

    です。

    普通の行列で考えれば、

    画像

    というイメージです。

    循環キューの問題では、この位置がどのように変化するかを追うことがあります。

    ⸻

    33.スタックの重要ワード

    スタックが出たら、次のキーワードを連想しましょう。

    スタック
    ↓
    LIFO
    ↓
    後入れ先出し
    ↓
    push / pop
    ↓
    最後に入れたものから取り出す

    このセットで覚えるのがおすすめです。

    ⸻

    34.キューの重要ワード

    キューなら、

    キュー
    ↓
    FIFO
    ↓
    先入れ先出し
    ↓
    enqueue / dequeue
    ↓
    最初に入れたものから取り出す

    です。

    スタックと対にして覚えると整理しやすくなります。

    ⸻

    35.練習問題① スタック

    空のスタックに対して、

    push(A)
    push(B)
    push(C)
    pop()

    を実行しました。

    取り出されるデータは何でしょう?

    ⸻

    答え

    C

    です。

    最後に入れたCから取り出されます。

    LIFO

    ですね。

    ⸻

    36.練習問題② キュー

    空のキューに、

    enqueue(A)
    enqueue(B)
    enqueue(C)
    dequeue()

    を実行しました。

    取り出されるデータは何でしょう?

    ⸻

    答え

    A

    です。

    最初に入れたAから取り出されます。

    FIFO

    です。

    ⸻

    37.練習問題③ スタック

    次の処理を実行します。

    push(10)
    push(20)
    x ← pop()
    push(30)
    y ← pop()

    xとyはいくつでしょう?

    順番に追います。

    push(10)
    [10]

    ↓

    push(20)
    [10,20]

    ↓

    x ← pop()
    x = 20

    残りは、

    [10]

    ↓

    push(30)
    [10,30]

    ↓

    y ← pop()
    y = 30

    したがって、

    x=20

    y=30


    です。

    ⸻

    38.練習問題④ キュー

    次の処理を実行します。

    enqueue(10)
    enqueue(20)
    x ← dequeue()
    enqueue(30)
    y ← dequeue()

    順番に追います。

    [10]
    ↓
    [10,20]

    最初のdequeueで、

    x = 10

    残りは、

    [20]

    30を追加して、

    [20,30]

    次のdequeueで、

    y = 20

    です。

    したがって、

    x=10

    y=20


    となります。

    ⸻

    39.練習問題⑤ スタック+繰返し

    少し科目Bらしくします。

    for i = 1 to 4
       push(i)
    endfor

    x ← pop()

    とします。

    ループ終了時点では、

    画像

    です。

    ここからpopするので、

    x=4

    です。

    ⸻

    40.練習問題⑥ キュー+繰返し

    次は、

    for i = 1 to 4
       enqueue(i)
    endfor

    x ← dequeue()

    です。

    ループ終了時点では、

    [1,2,3,4]

    です。

    dequeueすると最初のデータが取り出されるため、

    x=1

    となります。

    ⸻

    41.練習問題⑦ 少し応用

    空のスタックに対して、

    push(1)
    push(2)
    x ← pop()
    push(x + 3)
    y ← pop()

    を実行します。

    順番に追います。

    まず、

    [1]

    ↓

    [1,2]

    ↓

    x ← pop()

    なので、

    x = 2

    残りは、

    [1]

    です。

    次に、

    push(x + 3)

    なので、

    push(5)

    となります。

    状態は、

    [1,5]

    最後に、

    y ← pop()

    なので、

    y=5

    です。

    ⸻

    42.科目Bでの解き方

    スタック・キューが出てきたら、次の順番で確認するのがおすすめです。

    STEP1
    スタックかキューか確認

    ↓

    STEP2
    LIFOかFIFOか確認

    ↓

    STEP3
    初期状態を確認

    ↓

    STEP4
    追加操作を1つずつ実行

    ↓

    STEP5
    取出し操作のたびに状態を更新

    ↓

    STEP6
    変数へ代入された値を記録

    この順番なら、複雑な問題でもかなり整理しやすくなります。

    ⸻

    43.問題用紙には状態を書く

    例えばスタックなら、

    A
    ↓
    A B
    ↓
    A B C
    ↓
    A B

    のように状態を書いていきます。

    キューなら、

    [A]
    ↓
    [A,B]
    ↓
    [A,B,C]
    ↓
    [B,C]

    のように書きます。

    見た目が多少雑でもOK。

    頭の中だけで処理しない

    ことの方が重要です。

    ⸻

    44.スタック・キューと科目Bの擬似言語

    スタックとキューだけ単独で覚えて終わりではありません。

    科目Bでは、

    変数

    条件分岐

    繰返し

    配列

    関数


    などと組み合わされる可能性があります。

    例えば、

    for
    ↓
    条件判定
    ↓
    push
    ↓
    pop
    ↓
    変数へ代入

    のように複数の要素が混ざります。

    だからこそ、

    基本操作を見た瞬間に意味が分かる状態

    にしておくことが大切です。

    ⸻

    45.暗記ではなく動きを説明できるか確認する

    次の質問に答えられるか確認してみましょう。

    Q.スタックとは?
    → 最後に入れたデータから取り出す。

    Q.キューとは?
    → 最初に入れたデータから取り出す。

    Q.LIFOとは?
    → Last In, First Out。

    Q.FIFOとは?
    → First In, First Out。

    Q.pushとは?
    → スタックへ追加。

    Q.popとは?
    → スタックから取り出す。

    Q.enqueueとは?
    → キューへ追加。

    Q.dequeueとは?
    → キューから取り出す。

    ここまで即答できれば、基本はかなり固まっています。

    ⸻

    46.試験直前チェックリスト

    最後に確認してみましょう👇

    ☐ スタックとキューの違いを説明できる
    ☐ LIFOの意味が分かる
    ☐ FIFOの意味が分かる
    ☐ スタック=後入れ先出しと分かる
    ☐ キュー=先入れ先出しと分かる
    ☐ pushの意味が分かる
    ☐ popの意味が分かる
    ☐ enqueueの意味が分かる
    ☐ dequeueの意味が分かる
    ☐ A→B→Cをスタックから取り出す順番が分かる
    ☐ A→B→Cをキューから取り出す順番が分かる
    ☐ 操作ごとに状態をトレースできる
    ☐ ループと組み合わされても追える
    ☐ 循環キューの基本イメージが分かる

    怪しい項目があれば、その部分だけもう一度確認しましょう。

    ⸻

    47.最後にこれだけ覚える

    時間がない人は、まずこの表を覚えてください👇

    画像

    さらに一言で覚えるなら、

    スタック → 最後に入れたものから出る

    キュー → 最初に入れたものから出る


    これです🔥

    ⸻

    まとめ

    スタックとキューは、名前だけで暗記すると混乱しやすいですが、

    「データをどの順番で取り出すのか」

    をイメージすれば難しくありません。

    スタックは、

    LIFO=後入れ先出し

    A → B → C
    取り出す
    C → B → A

    キューは、

    FIFO=先入れ先出し

    A → B → C
    取り出す
    A → B → C

    です。

    そして科目Bで大切なのは、用語を覚えるだけではなく、

    操作を1つずつトレースできること。

    問題が複雑になっても、

    データ構造を確認 → 初期状態を確認 → 1操作ずつ状態を書く

    という流れを崩さなければ、かなり解きやすくなります。

    スタック・キューが苦手な人は、まず簡単なpush/pop、enqueue/dequeueから繰り返し練習してみてください🔥

    ⸻

    📚 基本情報技術者試験を勉強している方へ

    このnoteでは、

    「基本情報の難しいテーマを、初学者でも理解できる形にする」

    をテーマに、科目A・科目Bの攻略記事を公開しています。

    今回のスタック・キューが理解できたら、次は、

    配列 → 探索 → ソート → 計算量 → 科目Bの擬似言語問題

    と進めていくと理解をつなげやすいです。

    試験前に見返せるよう保存して活用ください📌

    役に立ったら、スキ・フォローしてもらえると嬉しいです🙌

    あなたへのおすすめ