LinkedListソースコード分析-初期化とノードクエリ

一緒に書く習慣を身につけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して10日目です。クリックしてイベントの詳細をご覧ください

LinkedListソースコード分析-初期化

LinkedListの最下層はリンクリスト構造であり、コレクション要素の先入れ先出しおよび先入れ先出しのシナリオに適しています。

初期化

LinkedListの基礎となるデータ構造は、二重リンクリストです。二重リンクリストの特徴は次のとおりです。

  1. リンクリストの各ノードはノードと呼ばれます
  2. ノードには前のノード(prev)があり、これは前のノードの位置を表します
  3. ノードには次のノードがあり、これは次のノードの位置を表します
  4. 最初は二重リンクリストのヘッドノードであり、その前のノードはnullを指しています
  5. 最後は二重リンクリストのテールノードであり、その次のノードはnullを指します
  6. リンクリストにデータがない場合、最初と最後は同じノードであり、両方とも前後でnullを指します
  7. リンクリスト内の各ノードは、前方または後方にクエリできます
  8. 二重リンクリストにはメモリサイズの制限がなく、もちろんマシンの構成に制限されているのは当然のことです。

ノードのコンポーネント、ソースコード:

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
    transient int size = 0;

    /**
     * Pointer to first node.
     * Invariant: (first == null && last == null) ||
     *            (first.prev == null && first.item != null)
     */
    transient Node<E> first;

    /**
     * Pointer to last node.
     * Invariant: (first == null && last == null) ||
     *            (last.next == null && last.item != null)
     */
    transient Node<E> last;
    
    private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }    
    
    ......
}
复制代码
  1. E item;ノード値を表します
  2. Node<E> next;次のノードを表します
  3. Node<E> prev前のノードを表します
  4. Node(Node<E> prev, E element, Node<E> next)初期化パラメータ:前のノード、自分のノード値、次のノード

お問い合わせ

リンクリストクエリは比較的低速であり、ソースコードを見つけるために1つずつトラバースする必要があります。

    Node<E> node(int index) {
        // assert isElementIndex(index);

        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }
复制代码
  1. if (index < (size >> 1))インデックスがキューの前半にある場合は、最初から開始します
  2. for (int i = 0; i < index; i++)forループがインデックスの前のノードで停止するまで
  3. for (int i = size - 1; i > index; i--)インデックスがキューの後半にある場合は、forループがインデックスの次のノードで停止するまで、最後から検索を開始します。

LinkedListのクエリは、単純な二分法を採用しています。最初に、インデックスがリンクリストの前半にあるか後半にあるかを確認します。前半の場合は最初から始め、後半の場合は後ろから始めます。この移動により、クエリの平均数を半分に減らすことができます。

おすすめ

転載: juejin.im/post/7085605852006055973