C++の優先度付きキュー(priority_queue)の基本と使い方を解説
キュー(queue)は、先に入れた要素から順に取り出される「FIFO(First In First Out:先入れ先出し)」方式のデータ構造です。キューにはいくつかの派生形があり、その代表例がデック(Deque:両端キュー)と優先度付きキュー(Priority Queue)です。
優先度付きキューとは
優先度付きキューでは、キュー内の各要素がそれぞれ固有の優先度を持ちます。要素を挿入する際に優先度を割り当てておき、取り出すときは最も優先度の高い要素から順に削除されます。この性質により、「重要なタスクから順に処理する」ような場面で非常に役立ちます。
優先度付きキューを実装する最も簡単な方法のひとつが、ヒープ(heap)データ構造を使う方法です。ヒープを利用することで、最大(または最小)の要素を効率的に取得できます。
以下では、C++のSTL(標準テンプレートライブラリ)に用意されている std::priority_queue を使ったサンプルコードを紹介します。ここでは要素の値そのものを優先度として扱うため、より大きな値ほど高い優先度を持つことになります。
アルゴリズム
insert(key, priority):
キーをヒープの末尾に挿入する
優先度に基づいて配列をヒープ化する
End
delete():
item := ルート(先頭)の要素
root := 配列の最後の要素
優先度に基づいて配列をヒープ化し直す
return item
End
C++による実装例
次のコードでは、priority_queue<int> に複数の整数を push し、top() での参照や pop() による削除の様子を確認しています。
#include <iostream>
#include <queue>
using namespace std;
void dequeElements(priority_queue <int> que) {
priority_queue <int> q = que;
while(!q.empty()){
cout << q.top() << " ";
q.pop();
}
cout << endl;
}
int main() {
priority_queue <int> que;
que.push(10);
que.push(20);
que.push(30);
que.push(5);
que.push(1);
cout << "現在キューに保持されている要素 : ";
dequeElements(que);
cout << "キューのサイズ : " << que.size() << endl;
cout << "先頭位置にある要素 : " << que.top() << endl;
cout << "キューから削除 : ";
que.pop();
dequeElements(que);
cout << "キューから削除 : ";
que.pop();
dequeElements(que);
}
実行結果
現在キューに保持されている要素 : 30 20 10 5 1 キューのサイズ : 5 先頭位置にある要素 : 30 キューから削除 : 20 10 5 1 キューから削除 : 10 5 1
出力からわかるポイント
- 30 20 10 5 1 のように、値の大きい順(優先度の高い順)に要素が取り出されています。
pop()を呼び出すたびに、現時点で最も優先度の高い要素が先頭から削除されます。
主なメンバー関数
- push(): 要素をキューに追加します
- top(): 最も優先度の高い要素(この例では最大値)への参照を返します
- pop(): 最も優先度の高い要素を削除します
- size(): 現在格納されている要素数を返します
- empty(): キューが空かどうかを判定します
なお、std::priority_queue はデフォルトでは std::less を比較関数として使用するため最大値が先頭になります。std::greater<T> を第3引数に指定すれば、最小値を優先するキューとして動作させることができます。
-
C++で双方向リンクリストを使用した優先度付きキューの実装
整数値のデータと優先度が与えられ、その優先度に従って双方向リンクリスト(doubly linked list)を作成し、結果を表示することが本記事の課題です。 優先度付きキューとは? キュー(Queue)はFIFO(First In, First Out:先入れ先出し)方式のデータ構造であり、最初に挿入された要素が最初に取り出されます。優先度付きキュー(Priority Queue)は、要素の優先度に応じて挿入や削除を行えるキューの一種です。キュー、スタック、リンクリストなどのデータ構造を使って実装でき、本記事では双方向リンクリストを用います。 優先度付きキューは、次のルールに従って動作しま
-
メッセージキューを使ったプロセス間通信(IPC)の基礎と実装方法
共有メモリがあるのに、なぜメッセージキューが必要なのか?共有メモリという強力なIPC手段がすでにあるのに、なぜメッセージキューが必要なのでしょうか。その理由は複数あります。理解しやすいように、いくつかのポイントに分けて整理してみましょう。メッセージキューでは、あるプロセスがメッセージを受信すると、そのメッセージは他のプロセスからは利用できなくなります。一方、共有メモリでは、複数のプロセスが同じデータに同時にアクセスできます。小さなサイズのメッセージ形式で通信したい場合に適しています。共有メモリでは、複数のプロセスが同時に通信する際、同期処理によってデータを保護する必要があります。共有メモリへの