STL priority_queue
で十分に機能するアプリケーション(C++)を持っています。 ドキュメント は言う:
Priority_queueはコンテナーアダプターです。つまり、基になるコンテナータイプの上に実装されます。デフォルトでは、基になるタイプはベクターですが、別のタイプを明示的に選択することもできます。
そして
プライオリティキューは標準的な概念であり、さまざまな方法で実装できます。この実装はヒープを使用します。
私は以前にassumedtop()
がO(1)
であること、そしてPush()
はO(logn)
になるであろう(最初にpriority_queue
を選択した2つの理由)場所)-しかし、ドキュメントはこの仮定を確認も否定もしません。
より深く掘り下げて、Sequenceコンセプトのドキュメントはこう言っています:
単一要素の挿入と消去の複雑さはシーケンスに依存します。
priority_queue
は、vector
(デフォルト)をヒープとして使用します。
...要素へのランダムアクセス、最後の要素の一定時間の挿入と削除、および最初または中間の要素の線形時間の挿入と削除をサポートします。
デフォルトのpriority_queue
を使用すると、top()
はO(1)
であり、Push()
はO(n)
であると推測しています。
質問1:これは正しいですか? (top()
アクセスはO(1)
であり、Push()
はO(n)
?です)
質問2:set
を使用した場合、O(logn)
でPush()
効率を達成できますか?またはmultiset
の代わりにvector
)を使用してpriority_queue
を実装しますか?これを行うとどのような影響がありますか?結果として他のどのような作業が影響を受けるでしょうか?
注:スペースではなく、時間の効率が心配です。
プライオリティキューアダプターは、標準ライブラリヒープアルゴリズムを使用してキューを作成し、キューにアクセスします。これは、ドキュメントで検索する必要があるアルゴリズムの複雑さです。
Top()操作は明らかにO(1)ですが、おそらく Josuttis に従って)呼び出した後にヒープをpop()したいのでO(2 * log(N))とPush()はO(log(N))-同じソースです。
そしてC++標準、25.6.3.1、Push_heapから:
複雑さ:最大でログ(最後-最初)の比較。
そしてpop_heap:
複雑さ:最大2 * log(最後-最初)の比較。
top()
-O(1)-これは要素@ frontを返すだけなので。
Push()
-
Push_into_heap-多くても、log(n)の比較。 O(logn)
したがって、Push()の複雑さは-log(n)です。
いいえ、これは正しくありません。 top()はO(1)で、Push()はO(log n)です。ドキュメントのメモ2を読んで、このアダプターがベクターの反復を許可していないことを確認してください。Neilは正しいpop()についてですが、これでもO(log n)時間で挿入と削除を行うヒープを操作できます。
基礎となるデータ構造がヒープの場合、top()は一定の時間になり、Push(編集:およびpop)は対数になります(あなたが言っているように)。ベクトルは、これらを次のように格納するために使用されます。
ヒープ:
1
2 3
8 12 11 9
VECTOR(保存に使用)
1 2 3 8 12 11 9
これは、i番目の子の要素が(2i)および(2i + 1)であると考えることができます。
データを順次格納するため、ベクターを使用します(ディスクリートよりもはるかに効率的でキャッシュに優しい)。
格納方法に関係なく、popが一定で、Pushが対数になるように、ヒープを常に実装する必要があります(特にSTD libを作成した神々によって)。
C++ STL priority_queueの基礎となるデータ構造は、ヒープデータ構造です(ヒープは、完全なバイナリツリーと完全なバイナリツリーに基づく非線形ADTであり、ベクター(または配列)コンテナーを介して実装されます。
ex Input data : 5 9 3 10 12 4.
Heap (Considering Min heap) would be :
[3]
[9] [4]
[10] [12] [5]
NOW , we store this min heap in to vector,
[3][9][4][10][12][5].
Using formula ,
Parent : ceiling of n-1/2
Left Child : 2n+1
Right Child : 2n+2 .
Hence ,
Time Complexity for
Top = O(1) , get element from root node.
POP()= O(logn) , During deletion of root node ,there is chance to violation of heap order . hence restructure of heap order takes at most O(logn) time (an element might move down to height of tree).
Push()= O(logn) , During insertion also , there might chance to violation of heap order . hence restructure of heap order takes at most O(logn) time (an element might move up to root from leaf node).
Q1:標準は調べていませんが、AFAIKはvector
(またはdeque
btw)を使用しており、複雑さはO(1)
の場合top()
、 O(log n)
およびPush()
の場合はpop()
。私はかつてstd::priority_queue
を自分のヒープとO(1)
Push()
およびtop()
およびO(log n)
pop()
で比較しましたが、確かにそうではありませんでした。 t O(n)
と同じくらい遅い。
Q2:set
はpriority_queue
(シーケンスではない)の基礎となるコンテナーとして使用できませんが、O(log n)
Push()
およびpop()
。ただし、これはstd::priority_queue
の実装よりもstd::vector
のパフォーマンスの方が優れているとは言えません。