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

DEPQ(両端優先度キュー)の一般的な構築手法:デュアルヒープと対応付け技法を解説

はじめに

両端優先度キュー(DEPQ:Double Ended Priority Queue)は、最小要素と最大要素の両方へ効率的にアクセスできるデータ構造です。単一端の優先度キュー(PQ)のデータ構造のうち、remove(aNode)操作(指定したノードaNodeをPQから削除する操作)を効率的に実装できるものであれば、そこから効率的なDEPQデータ構造を導き出す一般的な手法が存在します。本記事では、その代表的な3つの手法「デュアル構造法」「全対応付け」「葉対応付け」について解説します。

デュアルヒープ(Dual Heap)

これらの手法の中で最も単純なのが「デュアル構造法(dual structure method)」です。この手法では、DEPQの全要素について最小ヒープ(min PQ)と最大ヒープ(max PQ)の両方を管理し、同じ要素に対応する最小ヒープのノードと最大ヒープのノードの間に、対応ポインタ(correspondence pointers)を設定します。

図Aは、要素7、8、3、6、5からなるデュアルヒープ構造を示したものです。対応ポインタは赤い矢印で表されています。

DEPQ(両端優先度キュー)の一般的な構築手法:デュアルヒープと対応付け技法を解説

図A:デュアルヒープ

図では各要素が最小ヒープと最大ヒープの両方に格納されているように見えますが、実際には各要素を2つのヒープのどちらか一方にのみ格納すれば十分です。

isEmpty操作やsize操作は、DEPQ内の要素数を記録する変数sizeを管理することで実現できます。最小要素は最小ヒープの根(ルート)に、最大要素は最大ヒープの根に位置します。要素Aを挿入する際は、Aを最小ヒープと最大ヒープの両方に挿入し、その後、両ヒープにおけるAの位置の間に対応ポインタを設定します。最小要素を削除する場合は、最小ヒープからremoveMinを実行するとともに、最大ヒープからremove(aNode)(aNodeは削除した要素に対応するノード)を実行します。最大要素の削除も同様の手順で行います。

全対応付けと葉対応付け(Total and Leaf Correspondence)

全対応付け(total correspondence)と葉対応付け(leaf correspondence)は、より洗練された対応付けの手法です。いずれの手法でも、要素の半分を最小PQに、残りの半分を最大PQに配置します。要素数が奇数の場合は、1つの要素をバッファに格納します。このバッファ内の要素は、どちらのPQにも所属しません。

全対応付け(Total Correspondence)

全対応付けの手法では、最小PQ内の各要素xが、最大PQの異なる要素yと1対1でペアになります。対応ペア(x, y)は、priority(x) <= priority(y) という関係を満たします。

図Bは、11個の要素3、4、5、5、6、6、7、8、9、10、11からなる全対応付けヒープを示しています。要素10がバッファに格納されており、対応ペアは赤い矢印で表されています。

DEPQ(両端優先度キュー)の一般的な構築手法:デュアルヒープと対応付け技法を解説

図B:全対応付けヒープ

葉対応付け(Leaf Correspondence)

葉対応付けの手法では、最小PQと最大PQの各葉(リーフ)要素が必ず対応ペアの一部である必要があります。一方、葉以外の要素は対応ペアに属する必要はありません。図Cは葉対応付けヒープの例です。

DEPQ(両端優先度キュー)の一般的な構築手法:デュアルヒープと対応付け技法を解説

図C:葉対応付けヒープ

3つの手法の比較

全対応付けと葉対応付けの構造は、デュアル構造よりも必要なメモリ領域が少なくて済むという利点があります。その一方で、全対応付けおよび葉対応付け構造におけるDEPQアルゴリズムは、デュアル構造のものよりも複雑になります。3つの対応付け手法の中では、葉対応付けが最も高速なDEPQ構造を提供するとされています。

計算量

上述の対応付け手法のいずれかを用いることで、ヒープ、高さバイアス左翼木(height biased leftist tree)、ペアリングヒープ(pairing heap)からDEPQ構造を構築できます。これらのDEPQ構造では、put(x)、removeMin()、removeMax()の各操作にO(log n)の時間がかかります(nはDEPQ内の要素数。ペアリングヒープの場合は償却計算量)。それ以外のDEPQ操作は、すべてO(1)の時間で実行できます。

  1. 【Python入門】線形探索(リニアサーチ)の仕組みと実装方法

    本記事では、最も基本的な探索アルゴリズムである「線形探索(リニアサーチ)」の仕組みと、Python 3.xでの実装方法について詳しく解説します。 線形探索とは 線形探索は、配列(リスト)の先頭から順番に要素を一つずつ調べ、目的の値と一致するかどうかを確認していくシンプルな探索手法です。データがソートされていなくても利用できるため、小規模なデータや整列されていないデータを扱う際に手軽で便利です。 アルゴリズムの手順 1. 配列 arr[] の左端(先頭)の要素から順に、目的の値 x と各要素を比較していく 2. x がいずれかの要素と一致した場合、そのインデックス(位置)を返す 3. 配列の最後

  2. Windows 10のリカバリディスクを作成する3つの方法【USB・CD/DVD対応】

    Windows 10のリカバリディスクがあれば、パソコンのOSを復元・修復できます。トラブルが発生してPCが起動しなくなったときでも、リカバリディスクを使えば問題を解決し、正常な状態に戻すことが可能です。Windows 10のリカバリディスクは比較的簡単に作成でき、その方法も複数あります。 この記事では、Windows 10の修復用USBを作成する3つの方法を紹介します。作成したUSBをPCに接続すれば、短時間でトラブルを解消できるでしょう。 方法1. Windows 10 PCでリカバリドライブを作成する 方法2. Windows 10のシステム修復ディスク(CD/DVD)を作成する 方法