Java容器详情三(LinkedList)

1. 俩表的概念
链表的概念,链表是由一些列的非连续的节点组成的存储结构,简单分下类的话,链表又分为单向链表和双向链表,而单向/双向链表又可以分为循环链表和非循环链表,下面简单就这四种链表进行简单的说明。

  • 单向链表是前面节点只指向后面节点,后面节点不指向前面节点,节点中只有一个成员存储下一个节点位置。
  • 双向链表是每个节点都有两个存储下一个和上一个节点位置的成员,链表可以上下游动。
  • 循环链表是链表的最后一个节点的尾指针指向头节点,头结点的上一个节点指针指向尾节点,在单向链表中就表现在尾节点的下一个节点指针指向头结点。
  • 非循环链表,就是尾节点的下一个节点指针指向空,双向链表中头结点的上一个节点指针和尾节点的下一个节点指针都是指向空的。

2. 底层存储结构
链表的底层存储实体结构为

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

由源码可知,LinkedList采用的双向链表结构。
链表的成员为

    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;

3. 添加元素
添加元素主要有两个方法,一个默认添加到链表末尾处,一个可以指定添加到指定的位置处。分别为:

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

public void add(int index, E element) {
        checkPositionIndex(index);

        if (index == size)
            linkLast(element);
        else
            linkBefore(element, node(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;
        }
    }
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++;
    }

2. 删除元素,修改元素
剩下的操作比较简单,就不在赘述。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、基本数据类型 注释 单行注释:// 区域注释:/* */ 文档注释:/** */ 数值 对于byte类型而言...
    龙猫小爷阅读 4,290评论 0 16
  • 本文内容取自于小甲鱼的数据结构与算法。http://www.jianshu.com/p/230e6fde9c75 ...
    阿阿阿阿毛阅读 2,936评论 0 7
  • 作为一个资深的新手程序员😂,链表这些既基础又深奥的东西是日常工作中并不常见,但是却非常重要,所以就总结一下链表的简...
    Clark_new阅读 4,301评论 4 12
  • B树的定义 一棵m阶的B树满足下列条件: 树中每个结点至多有m个孩子。 除根结点和叶子结点外,其它每个结点至少有m...
    文档随手记阅读 13,355评论 0 25
  • 汉文帝、汉景帝共在位四十年,期间按照黄老之学,与民休养,极大丰富了国家的人口数量和物质基础,史称其为“文景之治”。...
    懒虫小狮子阅读 139评论 0 0