LinkedList源码笔记

来源:互联网 发布:修改软件下载 编辑:程序博客网 时间:2024/06/08 07:16

链表结构

不同于数组与向量中各数据项的物理存放位置与逻辑次序完全对应,链表中的元素虽然也构成一个线性逻辑次序,但其元素的物理地址可以任意

链表中的元素维护一个前驱与后继,分别指向上一个元素与下一个元素的地址。

头尾节点与首末节点

链表结构中,除了可见的首末节点first、last,还有不可见的头尾节点header、trailer。

创建链表时即创建头尾节点,first时头节点的后继,last是尾节点的前驱。这种设计方法使得相关算法不必再对各种边界退化情况做专门处理。

Java中对链表的实现LinkedList

LinkedList中实现了一个内部私有类,其中next指向下一个节点,prev指向前一个节点,item是当前节点的值

    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;        }    }

另外还有两个内部私有变量size与modCount。

其中modCount用于记录LinkedList被修改的次数。

LinkedList提供两个构造方法

    public LinkedList() {}public LinkedList(Collection<? extends E> c) {    this();    addAll(c);}

LinkedList添加元素

在首次创建LinkedList时调用add(E e)函数,last == first == null。

将新创建的节点前驱指向LinkedList的last,即指向头节点null。

新节点newNode(l,e,null),将l即最后一个节点作为前驱,此时指向null。null作为后继,即指向不可见的尾节点,值为e。

将LinkedLits的last 指向新创建的节点。

满足 l == null,将LinkedList的first指向该节点。

此时列表中只有一个节点和隐含的两个不可见的头尾节点。


在LinkedList已有元素时调用add(E e),last指向最后一个节点,first指向第一个节点。

l = last 指向最后一个节点。

新节点newNode(l,e,null),将l即最后一个节点作为前驱。null作为后继,即指向不可见的尾节点,值为e。

将LinkedList的last替换为新节点newNode。

l != null,不满足条件语句将l的后继替换成新节点newNode,不再指向null。

    public boolean add(E e) {        linkLast(e);        return true;}void linkLast(E e) {    final Node<E> l = last;    final Node<E> newNode = new Node<>(l, e, null);    last = newNode;    if (l == null)        first = newNode;    else        l.next = newNode;    size++;    modCount++;}

在指定的索引处添加元素

当index == size,将e作为最后一个节点链接。

当index != size,将新节点(值为e)插入index的位置。node(index)的前驱作为新节点的前驱,node(index)作为新节点的后继。

    public void add(int index, E element) {        checkPositionIndex(index);//对index进行有效性判定        if (index == size)            linkLast(element);        else            linkBefore(element, node(index));    }    /**     * Links e as last element.     */    void linkLast(E e) {        final Node<E> l = last;        final Node<E> newNode = new Node<>(l, e, null);        last = newNode;        if (l == null)            first = newNode;        else            l.next = newNode;        size++;        modCount++;    }    /**     * Inserts element e before non-null Node succ.     */    void linkBefore(E e, Node<E> succ) {        // assert succ != null;        final Node<E> pred = succ.prev;        final Node<E> newNode = new Node<>(pred, e, succ);        succ.prev = newNode;        if (pred == null)            first = newNode;        else            pred.next = newNode;        size++;        modCount++;    }    /**     * Returns the (non-null) Node at the specified element index.     */    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;        }    }

删除节点,默认删除首节点。

    public E remove() {        return removeFirst();    }    public E removeFirst() {        final Node<E> f = first;        if (f == null)            throw new NoSuchElementException();        return unlinkFirst(f);    }    private E unlinkFirst(Node<E> f) {        // assert f == first && f != null;        final E element = f.item;        final Node<E> next = f.next;        f.item = null;        f.next = null; // help GC        first = next;        if (next == null)            last = null;        else            next.prev = null;        size--;        modCount++;        return element;    }

清除整个节点

    public void clear() {        // Clearing all of the links between nodes is "unnecessary", but:        // - helps a generational GC if the discarded nodes inhabit        //   more than one generation        // - is sure to free memory even if there is a reachable Iterator        for (Node<E> x = first; x != null; ) {            Node<E> next = x.next;            x.item = null;            x.next = null;            x.prev = null;            x = next;        }        first = last = null;        size = 0;        modCount++;    }
原创粉丝点击