数据结构与算法之四(链表)

来源:互联网 发布:脚本编程课程 编辑:程序博客网 时间:2024/06/05 04:10

链表的概念在学c++的时候就接触了,就是一个个节点,每个节点里存在对下一个节点的引用。大概结构如下:

class Node{   //节点的其他属性       ...   //引用下一个节点   Node next;}

这样一个个节点上一个连下一个就形成了链表,概念很简单。如果知道第一个节点的内存地址,那么可以顺藤摸瓜找到其他节点。这种存储方式的好处是插入和删除时不需要做移动操作,只要改一下next的指向即可。缺陷也很明显,查找Node得从第一个节点依次遍历。

这里有几个概念:单链表,双端双向链表,循环链表等可以查一下。跟队列有点像,但是队列我们之前见过的那种是用数组存储的,实际上也可以用这种链表来存储。

java中链表比较典型的实现是LinkedList。

public class LinkedList<E>    extends AbstractSequentialList<E>    implements List<E>, Deque<E>, Cloneable, java.io.Serializable//AbstractSequentialListpublic abstract class AbstractSequentialList<E> extends AbstractList<E> public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>从这里可以看出AbstractSequentialList包含了collectionlist的实现.我们上一节了解了collection中包含了各种操作以及迭代器。而list中其实也是collectionpublic interface List<E> extends Collection<E>注意这里还有Deque,前面聊过这个是双端队列,所以这个LinkedList实际上是一个双端链表。通过firstlast维护首尾节点transient Node<E> first;transient Node<E> last;从addAll方法可以看到这个链表的构建过程。核心代码如下:public boolean addAll(int index, Collection<? extends E> c) {        checkPositionIndex(index);        Object[] a = c.toArray();        int numNew = a.length;        if (numNew == 0)            return false;        Node<E> pred, succ;        if (index == size) {            succ = null;            pred = last;        } else {            succ = node(index);            pred = succ.prev;        }        //通过for循环将所有node通过next连接起来        for (Object o : a) {            @SuppressWarnings("unchecked") E e = (E) o;            Node<E> newNode = new Node<>(pred, e, null);            if (pred == null)                first = newNode;            else                pred.next = newNode;            pred = newNode;        }        if (succ == null) {            last = pred;        } else {            pred.next = succ;            succ.prev = pred;        }        size += numNew;        modCount++;        return true;    }

说白了就是开头我画的那点东西。

原创粉丝点击