2012-02-28 18 views
3

キューのようなデータ構造があり、任意のポイントでのエレメントの削除もサポートしていますか?エンキューおよびデキューは最も頻繁に発生しますが、中途半端な要素の削除はスピードの点で似ている必要があります。なぜなら、それが最も一般的な操作である期間があるからです。絶対速度よりもパフォーマンスの一貫性が重要です。時間は記憶より重要です。キューの長さは、絶対最大負荷で1,000要素以下では小さくなります。明白でない場合は、明示的に述べます:ランダム挿入は不要です。ランダムアクセスエレメントを削除したキューのようなデータ構造

これは私の実装言語であるため、C++にタグ付けされていますが、私はSTLまたはBoostを使用していません。 (C言語のソリューションをC++クラスに変換します)

編集:私が望むのは、キューインターフェイス(または辞書インターフェイスも持つキュー)を持つ種類の辞書です。私はこのようなことを行うことができるように:

Container.enqueue(myObjPtr1); 
MyObj *myObjPtr2 = Container.dequeue(); 
Container.remove(myObjPtr3); 
+1

なぜSTLまたはブーストしないのですか?彼らは純粋なC + +です。それ以外の場合は、独自のデータ構造を記述する必要があります。 – DumbCoder

+1

STLはありませんか?それから、あなた自身で書く必要があります。私は左の子にいくつのノードがあるかのカウントを更新してツリーに行きます。すべてlog(n)する必要があります。 –

+2

'(私はC++クラスでCの解を包みます)'私はこれ以上読むことを拒否します –

答えて

4

私は(あなたがプライオリティキューをしたくないと仮定)、ダブルリンクリストが正確に何をしたいと思い:

  1. 速く簡単との両方に要素を追加する
  2. 簡単かつ要素の迅速な除去を終了しますに包まれた(

どこからでもあなたはstd::listコンテナを使用することができますが、(あなたのケースでは)あなたが唯一の要素へのポインタ(または参照)を持っている場合は、リストの途中から要素 を除去することは困難ですSTLのリスト)、しかし イテレータはありません。イテレータを使用している(例えばそれらを格納している)場合はオプションではありません - ダブルリンクリスト(要素カウンタでさえ)を実装するのはかなり簡単です。あなたがあなた自身のリストを実装する場合 - あなたは直接要素(それらのそれぞれは、その隣人の両方へのポインタが含まれています)へのポインタを操作することができます。あなたはブーストやSTLを使用したくない場合は、これはおそらく最良の選択肢(と最も簡単な)で、あなたは(あなたも物事をスピードアップするために、リストの要素のための独自のブロックアロケータを書くことができます)、すべての制御を持っています。

+1

リンクリストでは、「find every **」という要素はリスト内の要素が 'O(n)'であるため、「every elements where」の高速削除を許可していないことに注意してください。値 'k' [またはインデックス' i']の要素を削除するように求められた場合は、それを取得するために 'O(n)'になります。 – amit

+0

それでは、あなたは私の解説を理解して読まなかった。 ** list要素**へのポインタを持っていれば、他に何が必要なのでしょうか? – sirgeorge

+0

これは面白いと思います。ありがとう、アプローチはうまくいくはずです。私はそれを調べます。 –

3

1つのオプションは、(ログOとともに、各要素へのランダムアクセスを(n個のログを記録)順序統計ツリー、Oをサポート増強ツリー構造を使用することですn)任意の点での挿入と削除。内部的には、注文統計ツリーは、それに関連付けられた余分な情報をバランスよくバイナリ検索するトレイルとして実装されています。その結果、ルックアップは標準ダイナミック配列よりも遅くなりますが、挿入がはるかに高速です。

希望すると便利です。

+0

endへの挿入/削除は、dequeより遅くなりますが、途中では速くなります。 –

+0

ありがとうございました。検索は他のいくつかの質問を超えて、これらの点でかなり上がっていませんでした。 –

+1

@Tim Kemp-この実装はC:http://www.geeksforgeeks.org/archives/10379で見つかりました。私はしばらくの間、この構造体をC++で実装したいと思っていましたので、私は自由な時間があるときにそれを行うかもしれないと思います。私がしたら、私はここにそれを掲示するでしょう。 – templatetypedef

2

リンクされたリストやハッシュテーブルの組み合わせを使用することができます。 javaでは、それはLinkedHashSetと呼ばれます。

アイデアは、要素のリンクリストを有する、単純であり、また(key,nodes)hash mapを維持し、nodeは、リンクされたリスト内の関連ノードへのポインタであり、そしてkeyこのノードを表す鍵です。基本的な実装がsetであり、いくつかの余分な作業がdupesを許可し、このデータ構造を作るために必要とされるであろうことを

注意。

このデータ構造では、O(1)ヘッド/テールアクセスと、リスト内の任意の要素へのアクセスO(1)の両方にアクセスできます。[平均してすべて平均化された]

+0

補足として、これは 'std :: unordered_set'とBoost.Intrusiveリストで簡単に実装できます。 –

+0

ちょっと考えました - キューに重複した要素があるとどうなりますか?どのようにそれらを区別しますか?また、インデックスで削除する場合は、これをどのようにサポートしますか? – templatetypedef

+1

@templatetypedef:前述したように、重複をサポートするためにはもっと多くの作業が必要です。可能な解決策は 'map >'であるかもしれませんが、あなたのリストに多数の捨て句があるときは苦しんでいます。インデックスによる削除は実際には 'LinkedHashSet'では問題になります。効率的に行うための解決方法はリストをスキップリスト(インデックスカウント付き)に変換する必要があり、結果はO(ログ)になります。 'LinkedHashSet'の' O(1) 'パフォーマンスは無料ではありません。 – amit

関連する問題