数据结构之链表(附:数组与链表对比、ArrayList/LinkedList源码分析)

来源:互联网 发布:下载订票软件 编辑:程序博客网 时间:2024/05/16 09:58

1、什么是链表?

链表由节点组成;每个节点包含一些数据和节点的引用;最后一个节点的引用为空。

由于单链表只能向后遍历、效率低下、操作受限,所以本文章以双向链表为例

2、链表结构

2.1、节点类源码

prev:对上一个节点的引用

item:当前节点的元素

next:对下一个节点的引用

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


3、增删改查操作

3.1、添加节点

3.1.1、链表中添加节点

先说最简单的,在链表中间插入一个新的节点:

①:创建新节点,为其赋值前后节点的引用

②:将新节点前一个节点的引用指向新节点

③:将新节点后一个节点的引用指向新节点

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

3.1.2、链表头添加节点

然后是在链表头添加节点,较少的使用量:

①:创建新节点,将新节点后一个节点的引用指向原起始节点(first)

②:将原起始节点(first)的前一个节点引用指向新节点

    private void linkFirst(E e) {        final Node<E> f = first;        final Node<E> newNode = new Node<>(null, e, f);        first = newNode;        if (f == null)            last = newNode;        else            f.prev = newNode;        size++;        modCount++;    }

3.1.3、链表尾添加节点

最后是在链表尾添加节点,这是开发人员最常用的操作:

①:创建新节点,将新节点前一个节点的引用指向原结束节点(last)

②:将原结束节点(last)的后一个节点引用指向新节点

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

3.2、删除节点

①:判断前一个节点的引用是否为空。

          如果为空,将起始节点first赋值为当前节点的下一个节点的引用(next);

          如果不为空,将前一个节点对下一个节点的引用(next)赋值为当前节点的下一个节点(next)

②:判断后一个节点的引用是否为空。

          如果为空,将结束节点last赋值为当前节点的上一个节点的引用(first);

          如果不为空,将后一个节点对上一个节点的引用(prev)赋值为当前节点的上一个节点(prev)

③:将当前节点的元素赋值为空(null),帮助垃圾回收

    E unlink(Node<E> x) {        // assert x != null;        final E element = x.item;        final Node<E> next = x.next;        final Node<E> prev = x.prev;        if (prev == null) {            first = next;        } else {            prev.next = next;            x.prev = null;        }        if (next == null) {            last = prev;        } else {            next.prev = prev;            x.next = null;        }        x.item = null;        size--;        modCount++;        return element;    }

3.3、改/查节点

3.3.1、查节点

这个就不用解释了吧。。。

    public E get(int index) {        checkElementIndex(index);        return node(index).item;    }

3.3.2、改节点

同上。。。

    public E set(int index, E element) {        checkElementIndex(index);        Node<E> x = node(index);        E oldVal = x.item;        x.item = element;        return oldVal;    }

阅读全文
0 0
原创粉丝点击