web-dev-qa-db-ja.com

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

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

  • バック()
  • Push_back()
  • pop_back()

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

Deque再配置では、push_front()が効率的な操作になるように、front()の前に要素のバッファーを与えませんか?これらの要素はスタックのコンテキストで使用されることがないため、無駄になりませんか?

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


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

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

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

85
Greg Rogers

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

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

72
Michael Burr

Vectorとdequeの相対的なメリットについては、Herb Sutterの Guru of the Week 54 を参照してください。

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

12
James Hopkin