1. 程式人生 > >LinkedList - 好一個雙向鏈表

LinkedList - 好一個雙向鏈表

true 獲取 pre ast 新節點 集合 末尾 turn poll()

LinkedList是常用的集合結構之一,數據存儲結構為鏈式存儲,每個節點都有元素、前指針和後指針,指針指向了前節點和後節點的位置。同是LinkedList也是一個隊列,實現了Deque接口,Deque接口繼承了Queue接口。

1.7以前為雙向循環鏈表,之後沒有循環了哦。

隊列出入順序為FIFO,插入的位置是隊列的尾部,而移出的位置是隊頭,Queue接口提供了offer()入列,和poll()出列的方法。

LinkedList的add(E e)方法:
public boolean add(E var1) {
        this.linkLast(var1);
        return true;
}

再來看this.linkLast(var1)方法:

void linkLast(E var1) {
        LinkedList.Node var2 = this.last;    //內部初始提供了first和last兩個節點
        LinkedList.Node var3 = new LinkedList.Node(var2, var1, (LinkedList.Node)null);     //構造一個新的Last節點,前指針指向原來的last節點var2 ,後指針為null
        this.last = var3;    //將var3 賦值給last節點
        if (var2 == null) {    //var2 為空 表示整個LinkedList沒有任何元素,第一次加入,此時first節點和last節點都為var3
            this.first = var3;
        } else {    //不為空則將原last節點的後指針指向var3
            var2.next = var3;
        }

        ++this.size;
        ++this.modCount;
}
LinkedList的add(int var1, E e)方法
public void add(int var1, E var2) {
        this.checkPositionIndex(var1);    //var1範圍檢查
        if (var1 == this.size) {    //如果var1==size 則直接再末尾添加一個節點
            this.linkLast(var2);
        } else {
            this.linkBefore(var2, this.node(var1));    //這裏node方法找到var1下標對應的元素,在此元素前面插入新節點
        }

}
LinkedList.Node<E> node(int var1) {
        LinkedList.Node var2;
        int var3;
        if (var1 < this.size >> 1) {    //判斷var1和中位值的大小,小於則從first節點開始向後遍歷,大於則從last節點開始向前遍歷
            var2 = this.first;

            for(var3 = 0; var3 < var1; ++var3) {
                var2 = var2.next;
            }

            return var2;
        } else {
            var2 = this.last;

            for(var3 = this.size - 1; var3 > var1; --var3) {
                var2 = var2.prev;
            }

            return var2;
        }
}
void linkBefore(E var1, LinkedList.Node<E> var2) {
        LinkedList.Node var3 = var2.prev;
        LinkedList.Node var4 = new LinkedList.Node(var3, var1, var2);
        var2.prev = var4;
        if (var3 == null) {    //若只有一個元素,則first節點為null
            this.first = var4;
        } else {
            var3.next = var4;
        }

        ++this.size;
        ++this.modCount;
}

再來看一下重寫的offer和poll方法

public boolean offer(E var1) {
        return this.add(var1);
}
插入的時候調用的是linkLast方法,及last節點為入列口,是隊尾

public E poll() {
        LinkedList.Node var1 = this.first;
        return var1 == null ? null : this.unlinkFirst(var1);
}
移除的時候調用了this.unlinkFirst(var1)方法
private E unlinkFirst(LinkedList.Node<E> var1) {
        Object var2 = var1.item;    //獲取first節點的數據返回
        LinkedList.Node var3 = var1.next;    //first節點的last節點
        var1.item = null;    //help GC
        var1.next = null;    //first節點的next節點指向null
        this.first = var3;    //現在first節點為var3
        if (var3 == null) {    //如果為null 則說明最開始first沒有next元素,鏈表為空或者只有一個first元素,現在移除了first元素,鏈表裏沒有元素了,last為null
            this.last = null;
        } else {    //first節點的prev節點為null
            var3.prev = null;
        }

        --this.size;
        ++this.modCount;
        return var2;
    }

LinkedList - 好一個雙向鏈表