2012-02-07 7 views
6

java.util.LinkedListでは、リスト内の特定のオブジェクトをすばやく削除することはできません。 remove(object)メソッドは線形検索を実行してリスト内のオブジェクトを見つけ出し、削除することができます。これは二重リンクリストなので、ポインタ(node.prevとnode.next)を更新するだけで削除できます。ノードの高速削除をサポートするJavaリンクリスト?

この問題のJava標準ソリューションとは何ですか。

注1:反復処理中は削除したくありません。私はそれが速いことを知っていますが、私は最初に私の要素を反復しているわけではありません。

NOTE 2:私がそれが二重リンクリストに入っていることを知っているオブジェクトOが与えられていれば、それを線形検索しなくてもそのリストから(ポインタを更新することによって)素早く削除したいリストはjava.util.LinkedListのように

+4

イテレータを使用して削除すると、再度検索は実行されません。 – Dervall

+1

私はあなたの質問を理解していないか、二重リンクリストの仕組みを理解していません。リンクリストを使用する必要がありますか?ストレージの別のカテゴリがおそらく適切でしょうか?あなたがあなたが本当に*得ていることを理解するのを助けるために加えることができる任意の明確化? –

+0

メモを追加しました。私は反復中に削除したくない。 – chrisapotek

答えて

14

LinkedHashSetクラスをご覧ください。基本的には、エントリ間に二重リンクリストを保持するのはHashSetです。これは、O(1)の要素の検索(したがってうまくいけば)もサポートします。エントリやその他の詳細を再挿入する場合の要素の順序をどのように処理するかについては、仕様のリンクを確認してください。

EDIT:あなたは重複を格納する必要がある場合

あなたはGuavaLinkedHashMultiset(これまでに使用されることはありません)を見てみることができます。 MultisetのGuavaユーザーガイドはhereです。

+0

それはこれまでのところ最良の選択肢のように見えます。もちろん、唯一の欠点は、リスト内の重複をサポートしていないことです。 – chrisapotek

+0

等価を実装できます(または実装していない)ので、重複はありません。 –

+0

あなたは正しいです。 LinkedHashSetはHashSetを拡張しているため、重複は許されません(1つのヌル値だけです)。 @PeterLawrey HashStuffを扱うときに等号やハッシュコードを実装しないように注意してください... pavelrappo:| ?? – Gevorg

0

通常、可能であればListIteratorを使用して作業します。 removeは一定の時間になります。

Java標準ライブラリにはリンクリストのノード構造がありませんので、ListIteratorが最適です。

+0

リスト内の項目を検索する必要があります。これはO(n)時間です。それが見つかると、はい、削除するとO(1)になります。 – stackoverflowuser2010

1

複合オブジェクトが必要なようです。あなたのリストを含むクラスを作成し、そのリストへのインデックスも維持します。

したがって、高速削除を実行するには、削除するリスト要素への参照を取得するために一定の時間インデックスルックアップを行い、次に一定の時間を削除します。

2

LinkedList#remove()の実装では、前のアイテムと次のアイテムのポインタを更新することで削除されます。問題は、削除するアイテムが見つかるまですべてのオブジェクトをループしなければならないことです。

すべてのオブジェクトに対して反復処理を行わずにすばやく削除するコレクションが必要な場合は、SetまたはMapを使用します。

0

おそらく地図が適切でしょう。これは、が期待される O(1)除去時間を与える。しかし、再びあなたは何を指定しなかったのですか速くを意味します。

BSTを利用したリストも有効です。それはlog(n)除去時間を与えるでしょう。

ここに挙げられているソリューションでは、リストを反復するより速いものを想定していました。したがって、O(n)より速いものです。

1

私は主にJavaを学ぶCプログラマーです。私はこのスレッドを見つけました。なぜなら、それを検索せずに直接オブジェクトを削除できるリンクされたリストの実装がないのはなぜだろうかと疑問に思っていたからです。線形検索は非常に非効率的です。ハッシュテーブルで裏付けされたリストが優れていますが、実際にハッシュテーブルの実行方法はわかりません。

これをCで簡単に実行できる理由は、通常、リスト要素オブジェクト自体に次のポインタと前のポインタが含まれているため、オブジェクトを指定すると、ポインタを操作してリストから要素を削除するだけです、それはO(1)操作です。 Javaでは、オブジェクトがありますが、リスト内で別々に管理されているため、ポインタに直接アクセスすることはできません。したがって、オブジェクトを線形に、またはハッシュテーブルで検索する必要があります。

リストに追加されたすべてのオブジェクトタイプがLinkedListElementインターフェイスを実装し、次のポインタと前のポインタを取得して設定するリンクリスト実装を作成すると、この問題を解決できるようです。クラスに次のポインタと前のポインタを追加し、それを取得して設定する関数を実装する必要があります。リンクリストクラスは、オブジェクト自体にポインタが含まれているため、オブジェクトを簡単に削除することができます。

関連する問題