• Java中LinkedList实现原理


    数据结构

      LinkedList是基于链表结构实现,所以在LinkedList类中包含了first和last两个指针(类型为Node)。Node中包含了对prev节点、next节点的引用,这样就构成了双向的链表。

     1   private static class Node<E> {
     2         E item;
     3         Node<E> next;
     4         Node<E> prev;
     5 
     6         Node(Node<E> prev, E element, Node<E> next) {
     7             this.item = element;
     8             this.next = next;
     9             this.prev = prev;
    10         }
    11     }

    存储

    1.add(E e)方法

      该方法首先声明一个新Node l,将链表的最后一个Node赋值给l,然后将新的Node即newNode覆盖last(或者说让last指向newNode),最后将l的next指针指向newNode。

     1   //Appends the specified element to the end of this list.
     2     public boolean add(E e) {
     3         linkLast(e);
     4         return true;
     5     }
     6     /**
     7      * Links e as last element.
     8      */
     9     void linkLast(E e) {
    10         final Node<E> l = last;
    11         final Node<E> newNode = new Node<>(l, e, null);
    12         last = newNode;
    13         if (l == null)
    14             first = newNode;
    15         else
    16             l.next = newNode;
    17         size++;
    18         modCount++;
    19     }

    2.add(int index, E element)

      该方法是在指定的index位置插入新元素。如果index位置正好等于size,则调用linkLast(element)将其插入到末尾;否则调用linkBefore(element, node(index))方法进行插入。

      linkBefore中的node(index)是返回指定位置的元素。

     1   public void add(int index, E element) {
     2         checkPositionIndex(index);
     3         if (index == size)
     4             linkLast(element);
     5         else
     6             linkBefore(element, node(index));
     7     }
     8     /**
     9      * Returns the (non-null) Node at the specified element index.
    10      */
    11     Node<E> node(int index) {
    12         // assert isElementIndex(index);
    13         // 如果要取元素的位置是整个list一半的左半边,那么从list的头开始向后遍历,遍历至要取元素的位置
    14         if (index < (size >> 1)) {
    15             Node<E> x = first;
    16             for (int i = 0; i < index; i++)
    17                 x = x.next;
    18             return x;
    19         } 
    20         // 否则从list一半的右半边开始寻找,也就是从尾部开始向前遍历,遍历至要取元素的位置
    21         else {
    22             Node<E> x = last;
    23             for (int i = size - 1; i > index; i--)
    24                 x = x.prev;
    25             return x;
    26         }
    27     }

    删除

    1.remove(int index)

      删除列表中指定位置的元素,首先检测该位置是否在该列表中存在,然后解除该元素前、后指向的元素。

     1   public E remove(int index) {
     2         checkElementIndex(index);
     3         return unlink(node(index));
     4     }
     5     E unlink(Node<E> x) {
     6         // assert x != null;
     7         final E element = x.item;
     8         final Node<E> next = x.next;
     9         final Node<E> prev = x.prev;
    10 
    11         if (prev == null) {
    12             first = next;
    13         } else {
    14             prev.next = next;
    15             x.prev = null;
    16         }
    17 
    18         if (next == null) {
    19             last = prev;
    20         } else {
    21             next.prev = prev;
    22             x.next = null;
    23         }
    24 
    25         x.item = null;
    26         size--;
    27         modCount++;
    28         return element;
    29     }

    获取

    1.get(int index)

      获取指定位置元素的值。同样首先判断传入位置是否越界,如果超过list的size,抛出IndexOutBoundsException异常,然后node()方法进行左半边或右半边遍历获取,add(int index, E element)中有提到,不再赘述。

    1     public E get(int index) {
    2         checkElementIndex(index);
    3         return node(index).item;
    4     }

    2.getFirst()

    3.getLast()

      first、last是LinkedList的两个属性,判空后直接返回。

     1     /**
     2      * Returns the first element in this list.
     3      *
     4      * @return the first element in this list
     5      * @throws NoSuchElementException if this list is empty
     6      */
     7     public E getFirst() {
     8         final Node<E> f = first;
     9         if (f == null)
    10             throw new NoSuchElementException();
    11         return f.item;
    12     }
    13 
    14     /**
    15      * Returns the last element in this list.
    16      *
    17      * @return the last element in this list
    18      * @throws NoSuchElementException if this list is empty
    19      */
    20     public E getLast() {
    21         final Node<E> l = last;
    22         if (l == null)
    23             throw new NoSuchElementException();
    24         return l.item;
    25     }
  • 相关阅读:
    【leetcode】Recover Binary Search Tree
    【leetcode】Dungeon Game
    【leetcode】Text Justification
    【leetcode】Largest Number
    【leetcode】Merge k Sorted Lists
    【leetcode】Reverse Nodes in k-Group
    【leetcode】Multiply Strings
    【leetcode】Unique Binary Search Trees II
    hdu 1885 bfs+状压
    hdu 1429 bfs+状态压缩
  • 原文地址:https://www.cnblogs.com/zhengbin/p/6377994.html
Copyright © 2020-2023  润新知