std :: stackがデフォルトでstd :: dequeを使用するのはなぜですか?


91

コンテナをスタックで使用するために必要な操作は次のとおりです。

  • バック()
  • push_back()
  • pop_back()

なぜデフォルトのコンテナがベクターではなくデックなのですか?

deque再割り当ては、front()の前に要素のバッファーを提供しないので、push_front()は効率的な操作です。これらの要素はスタックのコンテキストで使用されることがないため、無駄になりませんか?

この方法でベクターの代わりに両端キューを使用するオーバーヘッドがない場合、priority_queueのデフォルトが両端キューではないベクトルでもあるのはなぜですか?(priority_queueには、front()、push_back()、およびpop_back()が必要です-基本的にスタックの場合と同じです)


以下の回答に基づいて更新:

dequeが通常実装される方法は、固定サイズ配列の可変サイズ配列であるようです。これにより、ベクター(再割り当てとコピーが必要)よりも速く成長するため、要素の追加と削除をすべて行うスタックのような場合は、dequeの方が適しています。

priority_queueでは、削除と挿入を行うたびにpop_heap()またはpush_heap()を実行する必要があるため、インデックスの作成が必要になります。要素の追加はとにかく定数で償却されるので、これはおそらくそこでベクトルをより良い選択にします。


1
「更新」の推論は完全に正しくありません。vectorは通常、両端より速く要素を追加および削除します。dequeは、要素をプッシュするのではなく、メモリを増やす方が高速です。
Mooing Duck、2015

回答:


75

コンテナーが大きくなるにつれて、ベクトルの再割り当てでは、すべての要素を新しいメモリブロックにコピーする必要があります。両端キューを大きくすると、新しいブロックが割り当てられ、ブロックのリストにリンクされます。コピーは必要ありません。

もちろん、必要に応じて、別のバッキングコンテナーを使用するように指定できます。したがって、あまり大きくならないことがわかっているスタックがある場合、それが好みの場合は、両端キューではなくベクトルを使用するようにスタックに指示してください。


1
しかし、ブロックへのポインターのリストが大きくなると、このリストは、ベクトルと同じように、時々再割り当てされる必要があります。漸近的に、効率の向上はせいぜい一定の要因によるものです。また、プッシュとポップを正しく行うために必要な反復子の操作は、のstd::deque場合よりもはるかに複雑std::vectorであり、これらの操作は再割り当てよりも頻繁に使用される可能性があります。私はstd::dequeこれがstd::vector実際に勝つと信じるのに苦労しています。
Marc van Leeuwen

@Michael Burr:listでは、なぜ使用しないのdequeか、なぜですか。
bappak

@MarcvanLeeuwenに関するあなたは、あなたが信じるのに苦労していると言います...明確な立場をとっていただけませんか?あなたは今、実際std::dequeに勝つチャンスがあると信じているというstd::vectorことですか、それともまだそれを疑っているということですか?ありがとう。
aafulei

@fleix私が個人的には実際のアプリケーションstd::dequeと同様にそれがうまくいくと信じるのが簡単な時間であるかどうかがなぜそれほど重要であるのかわかりませんstd::vector。しかし、その価値のために、私の個人的な経験では、1つの大きな複雑な重要なタスクではなく、コードに散りばめられた多くの小さな機会のために、スタックとキューのデータ構造が必要です。したがって、私は大規模な行動よりも、小規模な行動を重視しています。そして、dequeは特に鈍く輝いています。私の好みはどちらも使用せず、代わりに(自己実装)単一リンクリストを使用することです。しかし、走行距離は異なる場合があります。
Marc van Leeuwen、

12

ハーブサッターの第54週第一人者を参照して、vectorとdequeの相対的なメリットを比較してください。

priority_queueとqueueの間の不整合は、さまざまな人々がそれらを実装したことによるものだと思います。


2
priority_queueは実際にはpush / pop_frontを使用せず、最初の要素以外の要素への参照はヒープ操作によって無効になります。したがって、通常のキューの場合とは異なり、dequeの利点は適用されません。
Potatoswatter 2009

9
また、priority_queueソートしたままにする必要があるため、ランダムアクセスのオーバーヘッドが高いdeque::iteratorほど問題が多くなります。
Potatoswatter '19年

1
@Potatoswatter:priority_queue維持される「マジックオーダー」があり、ソートされていません。しかし、あなたの主張はそのままです。
Mooing Duck、2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.