どちらも、プリムのアルゴリズムに必要な最小値を取得し、キーを削除して再挿入して値を更新するように強制しているようです。この例だけでなく、一般的に言えば、一方を他方よりも使用することの利点はありますか?
一般的に言って、ヒープを使用して最小要素のみを追跡することはそれほど作業ではありません。
ツリーはより組織化されており、その組織を維持するにはより多くの計算が必要です。ただし、最小値だけでなく、anyキーにアクセスする必要がある場合は、ヒープだけでは不十分であり、ツリーの余分なオーバーヘッドが正当化されます。
その優先度付きキューでエリクソンに完全に同意すると、最小/最大要素のみが提供されます。
さらに、優先キューはデータの全順序を維持するのにそれほど強力ではないため、特別な場合には利点があります。 M
の配列内の最大のN
要素を追跡する場合、時間計算量はO(N*LogM)
になり、空間計算量はO(M)
になります。 。しかし、マップでそれを行う場合、時間計算量はO(N*logN)
であり、スペースはO(N)
です。これは非常に基本的なことですが、場合によっては優先キューを使用する必要があります。たとえば、M
は10のような定数です。
私が指摘したい2つの違いがあります(そしてこれは JavaのPriorityQueueとTreeSetの違い? この質問はこの質問の重複と見なされるため、より関連性があるかもしれません)。
(1)PriorityQueueは重複する可能性がありますが、TreeSetは重複することはできません。したがって、Treesetでは、コンパレータが2つの要素を等しいと見なした場合、TreeSetはそれらの2つの要素の一方のみを保持し、もう一方を破棄します。
(2)TreeSetイテレータはソートされた順序でコレクションをトラバースしますが、PriorityQueueイテレータはソートされた順序でトラバースしません。 PriorityQueueの場合アイテムを並べ替えられた順序で取得する場合は、remove()を繰り返し呼び出してキューを破棄する必要があります。
議論はこれらのデータ構造のJavaの実装に限定されていると思います。
それについての経験則は次のとおりです。
TreeMapは、すべての要素を整然と維持します。 (直感的には、構築に時間がかかります)
PriorityQueueは、最小または最大のみを保証します。安価ですが、強力ではありません。
それはすべてあなたが達成したいことに依存します。どちらかを選択する前に考慮すべき主なポイントは次のとおりです。
違いの1つは、remove(Object)とcontains(Object)が線形O(N)(Oracleのような)通常のヒープベースのPriorityQueue)であるが、O(log(N))。
したがって、要素が多数あり、remove(Object)またはcontains(Object)を多数実行する場合は、TreeSet/Mapの方が高速になる可能性があります。
優先度付きキューをどのように実装するかによって異なります。コーメンの本第2版によると、最速の結果はフィボナッチヒープです。