C++
 Computer >> コンピューター >  >> プログラミング >> C++

2つのスタックを使ってキューを実装するC++プログラム


スタック(Stack)とは

スタックはLIFO(Last In First Out:後入れ先出し)方式のデータ構造で、挿入と削除が同じ端(トップ)から行われます。最後に入れた要素が最初に取り出されます。

スタックの基本操作は次のとおりです。

  • push(int data) − トップに要素を挿入する
  • int pop() − トップから要素を削除して返す

キュー(Queue)とは

キューはFIFO(First In First Out:先入れ先出し)方式のデータ構造で、挿入は一方の端(リア)から、削除はもう一方の端(フロント)から行われます。最初に入れた要素が最初に取り出されます。

キューの基本操作は次のとおりです。

  • EnQueue(int data) − リア側に要素を挿入する
  • int DeQueue() − フロント側から要素を削除して返す

この記事では、2つのスタックを組み合わせてキューを実装するC++プログラムを紹介します。

各関数の動作

  • enQueue()関数:キューへ要素を追加します。
    • s1に値mをプッシュします。
  • deQueue()関数:キューから要素を取り出します。
    • 両方のスタックが空の場合は「Queue is empty」を表示して終了します。
    • s2が空の場合は、s1の全要素をs2へ移し替えます。
    • s2から要素をポップして返します。
  • push()関数:スタックに要素をプッシュします。
  • pop()関数:スタックから要素をポップします。

計算量のポイント

deQueue()では、s1の要素をまとめてs2へ移動することで順序が反転し、キューとしてFIFOの振る舞いを実現しています。各要素がスタック間を移動するのは高々2回だけなので、一連の操作全体で見ると償却計算量O(1)でキュー操作が可能です。

サンプルコード

#include <stdlib.h>
#include <iostream>
using namespace std;

struct nod { // ノードの宣言
    int d;
    struct nod *n;
};

void push(struct nod** top_ref, int n_d); // 関数プロトタイプ
int pop(struct nod** top_ref);

struct queue {
    struct nod *s1;
    struct nod *s2;
};

void enQueue(struct queue *q, int m) {
    push(&q->s1, m);
}

int deQueue(struct queue *q) {
    int m;
    if (q->s1 == NULL && q->s2 == NULL) {
        cout << "Queue is empty";
        exit(0);
    }
    if (q->s2 == NULL) {
        while (q->s1 != NULL) {
            m = pop(&q->s1);
            push(&q->s2, m);
        }
    }
    m = pop(&q->s2);
    return m;
}

void push(struct nod** top_ref, int n_d) {
    struct nod* new_node = (struct nod*) malloc(sizeof(struct nod));

    if (new_node == NULL) {
        cout << "Stack underflow \n";
        exit(0);
    }
    // スタックに要素を積む
    new_node->d = n_d;
    new_node->n = (*top_ref);
    (*top_ref) = new_node;
}

int pop(struct nod** top_ref) {
    int res;
    struct nod *top;
    if (*top_ref == NULL) { // スタックが空の場合
        cout << "Stack overflow \n";
        exit(0);
    } else { // スタックから要素を取り出す
        top = *top_ref;
        res = top->d;
        *top_ref = top->n;
        free(top);
        return res;
    }
}

int main() {
    struct queue *q = (struct queue*) malloc(sizeof(struct queue));
    q->s1 = NULL;
    q->s2 = NULL;
    cout << "Enqueuing..7" << endl;
    enQueue(q, 7);
    cout << "Enqueuing..6" << endl;
    enQueue(q, 6);
    cout << "Enqueuing..2" << endl;
    enQueue(q, 2);
    cout << "Enqueuing..3" << endl;
    enQueue(q, 3);

    cout << "Dequeuing..." << deQueue(q) << " " << endl;
    cout << "Dequeuing..." << deQueue(q) << " " << endl;
    cout << "Dequeuing..." << deQueue(q) << " " << endl;
}

実行結果

Enqueuing..7
Enqueuing..6
Enqueuing..2
Enqueuing..3
Dequeuing...7
Dequeuing...6
Dequeuing...2
  1. C++で多次元配列を使って2つの行列を乗算する方法【サンプルコード付き】

    行列とは行列(マトリックス)とは、数値を行と列の形式で長方形状に配置した配列のことです。例えば、3行3列からなる3×3行列は以下のように表されます。8 6 3 7 1 9 5 1 9この記事では、多次元配列を使用して2つの行列の積を計算するC++プログラムを紹介します。行列乗算プログラムの全体コード2つの行列を掛け合わせるC++プログラムは以下の通りです。サンプルコード#include<iostream> using namespace std; int main() { int product[10][10], r1=2, c1=3, r2=3, c2=3, i, j,

  2. C++で多次元配列を使って2つの行列を加算する方法を解説

    行列とは 行列(マトリックス)とは、数値を行と列の形式に整理して配置した長方形の配列のことです。行列は数学やプログラミングの分野で広く活用されており、画像処理やグラフ理論、線形代数の計算など、さまざまな場面で登場します。 例えば、以下のような4行3列の行列(4×3行列)が挙げられます。 3 5 1 7 1 9 3 9 4 1 6 7 このように、行列は「行数 × 列数」のサイズで表現されます。C++では、このような行列を多次元配列(2次元配列)として扱うことができます。 2つの行列を加算するC++プログラム それでは、多次元配列を使用して2つの行列を加算するC++プログラムを見ていきましょう