web-dev-qa-db-ja.com

std :: dequeは実際には最初に一定時間の挿入を持っていますか?

標準は言う:

両端キューは、ランダムアクセス反復子(27.2.7)をサポートするシーケンスコンテナーです。さらに、最初または最後の一定時間の挿入および消去操作をサポートします。途中で挿入と消去を行うと、線形時間がかかります。

ただし、同じ条項にも次のように記載されています。

この条項のすべての複雑さの要件は、含まれるオブジェクトに対する操作の数に関してのみ記述されています。 [例:vector<vector<int>>型のコピーコンストラクターは、含まれる各vector<int>のコピーの複雑さがそれ自体線形であるにもかかわらず、線形の複雑さを持っています。 —例を終了]

これは、たとえばdeque<int>の最初の挿入が線形timeをとらない限り許可されることを意味しません既に両端キューにあるintsと挿入される新しいintオブジェクトに対して、一定数の操作を実行しますか?

たとえば、「サイズKのベクターのベクター」を使用して両端キューを実装するとします。最初にK回挿入するたびに、新しいサイズKのベクトルを最初に追加する必要があるため、他のすべてのサイズKのベクトルを移動する必要があります。これは、最初の挿入の時間の複雑さが償却されることを意味しますO(N/K)ここで、Nは要素の総数ですが、Kは定数なので、これは単なるO(N)です。しかし、これは規格で許可されているようです。サイズKのベクトルを移動してもその要素は移動せず、含まれるintの「複雑さの要件」は「操作の数に関してのみ記載されている」ためです。オブジェクト。

規格はこれを本当に許可していますか?または、より厳しい要件があると解釈する必要がありますie含まれるオブジェクトに対する操作の定数数plus一定の追加時間?

8
Brian

複雑なドメインの意味をどのように解釈するかについては、少し進んでいると思います。あなたは、「線形時間」と「線形複雑さ」を区別しようとしているのですが、私には納得できません。

前部への挿入が一定時間であることは規格によって明確であり、私たちは皆、それに同意していると思います。後者のパッセージは、その下にある「一定の」操作数関与するのどれが単に規格によって指定または制約されていないかを示しています。

そして、これは珍しいことではありません。どのアルゴリズムも抽象化に基づいて機能します。個々の機械語命令に分類されるアルゴリズムを記述していて、アルゴリズムによって生成される機械語命令は[〜#〜] n [〜#〜]しかないと言ったとしても、個々の複雑度がプロセッサの内部にどのような複雑さを持っているかを調査して、それを結果に追加することはしません。一部の操作が量子分子レベルでより多くのことを行うことになるとは言えないため、O(n)アルゴリズムは実際にはO(N×Mまたは何か。そのレベルの抽象化は考慮しないことを選択しました。そして、その複雑さがアルゴリズムの入力に依存しない限り、それは完全に問題ありません。

あなたのケースでは、移動/コピーされた内部ベクトルのサイズは、dequeが大きくなるにつれて本質的に変化しないため、実際には関係ありません。内部ベクトルのnumberにはありますが、-各ベクトルのサイズは独立したプロパティです。したがって、新しい要素を外側のベクトルに挿入することの複雑さを説明する場合は無関係です。

実際の実行時間(選択した場合、それ自体がアルゴリズムの用語で説明される可能性があります)は、コピーされた内部ベクトルの内容によって異なりますか?はい、もちろん。しかし、これは、外側のベクトル自体が大きくなるにつれて、外側のベクトルを拡張するタスクワークロードで大きくなるとは関係ありません。

したがって、ここでは、標準は[〜#〜] n [〜#〜]またはN2またはlog N別のベクトルを前面に配置した場合の内部ベクトル。これらの操作の数は、両端キューが大きくなっても変化しないと言っています。また、そのルールの目的上、内部ベクトルのコピー/移動が実際に何を伴うか、またはそれらがどれほど大きいかは問題ではないことも述べています。

複雑性分析はパフォーマンスに関するものではありません。複雑性分析は、パフォーマンスのスケーリング方法に関するものです。