PR

【C#】キュー(Queue)とスタック(Stack)ってなに?操作の基本を学んでみよう!

【C#】
広告

はじめに

C#には、さまざまなコレクションが用意されていますが、その中でも「キュー(Queue)」と「スタック(Stack)」は非常に重要なデータ構造です。これらはプログラミングにおいて頻繁に使用されるため、その基本を理解することは非常に重要です。本記事では、キューとスタックの基本的な概念、操作方法、使用例を詳しく解説します。

キュー(Queue)

キューは、データを先入れ先出し(FIFO: First In, First Out)の順序で管理するデータ構造です。これは、列に並ぶ人々や、タスクを順番に処理する場合など、さまざまな場面で使用されます。

キューの基本操作

キューの宣言と初期化

C#でキューを使用するには、System.Collections.Generic名前空間のQueueクラスを使用します。

Queue<int> queue = new Queue<int>();

この例では、int型の要素を持つキューを宣言しています。

要素の追加

キューに要素を追加するには、Enqueueメソッドを使用します。

queue.Enqueue(1);
queue.Enqueue(2);
queue.Enqueue(3);

この例では、キューに順番に1, 2, 3が追加されます。

要素の削除

キューから要素を削除するには、Dequeueメソッドを使用します。

int first = queue.Dequeue();

この例では、キューの先頭にある1が削除され、firstに格納されます。

先頭の要素を参照

キューの先頭の要素を削除せずに参照するには、Peekメソッドを使用します。

int first = queue.Peek();

この例では、キューの先頭にある1が参照されますが、削除はされません。

キューの実践例

タスク管理

キューは、タスクを順番に処理する場合に便利です。

Queue<string> tasks = new Queue<string>();
tasks.Enqueue("Task 1");
tasks.Enqueue("Task 2");
tasks.Enqueue("Task 3");

while (tasks.Count > 0)
{
    string task = tasks.Dequeue();
    Console.WriteLine($"Processing {task}");
}

この例では、タスクが順番に処理され、出力されます。

サービスの待ち行列

キューは、サービスの待ち行列をシミュレーションする際にも使用されます。

Queue<string> serviceQueue = new Queue<string>();
serviceQueue.Enqueue("Customer 1");
serviceQueue.Enqueue("Customer 2");
serviceQueue.Enqueue("Customer 3");

while (serviceQueue.Count > 0)
{
    string customer = serviceQueue.Dequeue();
    Console.WriteLine($"Serving {customer}");
}

この例では、顧客が順番にサービスを受ける様子をシミュレーションしています。

スタック(Stack)

スタックは、データを後入れ先出し(LIFO: Last In, First Out)の順序で管理するデータ構造です。これは、プログラムの実行やメモリ管理など、さまざまな場面で使用されます。

スタックの基本操作

スタックの宣言と初期化

C#でスタックを使用するには、System.Collections.Generic名前空間のStackクラスを使用します。

Stack<int> stack = new Stack<int>();

この例では、int型の要素を持つスタックを宣言しています。

要素の追加

スタックに要素を追加するには、Pushメソッドを使用します。

stack.Push(1);
stack.Push(2);
stack.Push(3);

この例では、スタックに順番に1, 2, 3が追加されます。

要素の削除

スタックから要素を削除するには、Popメソッドを使用します。

int top = stack.Pop();

この例では、スタックの頂点にある3が削除され、topに格納されます。

頂点の要素を参照

スタックの頂点の要素を削除せずに参照するには、Peekメソッドを使用します。

int top = stack.Peek();

この例では、スタックの頂点にある3が参照されますが、削除はされません。

スタックの実践例

関数呼び出しの管理

スタックは、関数呼び出しの管理に使用されます。

void FunctionA()
{
    Console.WriteLine("Enter FunctionA");
    FunctionB();
    Console.WriteLine("Exit FunctionA");
}

void FunctionB()
{
    Console.WriteLine("Enter FunctionB");
    FunctionC();
    Console.WriteLine("Exit FunctionB");
}

void FunctionC()
{
    Console.WriteLine("Enter FunctionC");
    Console.WriteLine("Exit FunctionC");
}

FunctionA();

この例では、関数の呼び出しがスタックとして管理され、呼び出された順番とは逆に終了します。

戻り値の保存

スタックは、計算結果や状態を一時的に保存するためにも使用されます。

Stack<int> values = new Stack<int>();
values.Push(10);
values.Push(20);
int result = values.Pop() + values.Pop();
Console.WriteLine(result); // 30

この例では、スタックを使って計算結果を一時的に保存し、合計を計算しています。

キューとスタックの使い分け

キューとスタックは、用途によって使い分ける必要があります。

キューを使うべき場合

キューは、順序が重要な場合や、先に入れたものを先に処理する必要がある場合に適しています。たとえば、タスクの順番処理や、サービスの待ち行列などです。

スタックを使うべき場合

スタックは、逆順で処理する必要がある場合や、ネストされた処理を管理する場合に適しています。たとえば、関数の呼び出し管理や、ブラウザの履歴管理などです。

キューとスタックのパフォーマンス

メモリ管理

キューとスタックは、いずれもメモリ管理が重要です。大量のデータを扱う場合は、メモリの使用量に注意が必要です。

処理速度

キューとスタックの操作は、いずれも高速ですが、データの追加や削除の頻度によってはパフォーマンスに影響を与えることがあります。

キューとスタックの注意点

スレッドセーフ

キューやスタックをマルチスレッド環境で使用する場合、スレッドセーフであるかどうかに注意が必要です。標準のQueueStackクラスはスレッドセーフではないため、必要に応じてロックを使用するか、スレッドセーフなコレクションを使用する必要があります。

Queue<int> queue = new Queue<int>();
lock (queue)
{
    queue.Enqueue(1);
}

この例では、lock文を使用してスレッドセーフに操作を行っています。

無限ループ

キューやスタックの操作を行う際、無限ループに陥らないように注意が必要です。特に、条件を間違えると意図せず無限ループが発生する可能性があります。

while (queue.Count > 0)
{
    int item = queue.Dequeue();
    Console.WriteLine(item);
}

この例では、queue.Count > 0という条件を確認しているため、無限ループを避けることができます。

まとめ

本記事では、C#におけるキュー(Queue)とスタック(Stack)の基本について解説しました。キューとスタックの基本的な操作方法、実践的な使用例、使い分け、注意点について詳しく説明しました。キューとスタックは、プログラミングにおいて非常に重要なデータ構造であり、その基本を理解することで、より効果的にプログラムを作成できるようになるでしょう。これらのデータ構造をマスターして、C#プログラミングのスキルをさらに向上させてください。

広告
【C#】
広告
タイトルとURLをコピーしました