链表
链表(Linked List)
动态数组有个明显的缺点
- 可能会造成内存空间的大量浪费
 
能否用到多少就申请多少内存?
- 链表可以办到这一点
 
链表是一种链式存储的线性表,所有元素的内存地址不一定是连续的

接口设计
public interface List<E> {
    /**
     * 清除所有元素
     */
    void clear();
    /**
     * 元素的数量
     * @return
     */
    int size();
    /**
     * 是否为空
     * @return
     */
    boolean isEmpty();
    /**
     * 是否包含某个元素
     * @param element
     * @return
     */
    boolean contains(E element);
    /**
     * 添加元素到尾部
     * @param element
     */
    void add(E element);
    /**
     * 获取index位置的元素
     * @param index
     * @return
     */
    E get(int index);
    /**
     * 设置index位置的元素
     * @param index
     * @param element
     * @return 原来的元素ֵ
     */
    E set(int index, E element);
    /**
     * 在index位置插入一个元素
     * @param index
     * @param element
     */
    void add(int index, E element);
    /**
     * 删除index位置的元素
     * @param index
     * @return
     */
    E remove(int index);
    /**
     * 查看元素的索引
     * @param element
     * @return
     */
    int indexOf(E element);
}
虚拟头结点
- 有时候为了让代码更加精简,统一所有节点的处理逻辑,可以在最前面增加一个虚拟的头结点(不存储数据)
 - 不过这种方法也没有很精简,简单了解一下就行。
 

双向链表
- 此前所学的链表,也叫做单向链表
 - 使用双向链表可以提升链表的综合性能
 

- 只有一个元素
 

单向循环链表

只有1个节点

如何发挥循环链表的最大威力?

单向链表复杂度分析
- size 是数组规模 n
 

双向链表 vs 单向链表
粗略对比一下删除的操作数量 ,操作数量缩减了近一半
单向链表:
双向链表:
java的观法 JDK 中的 java.util.LinkedList, 使用的是双向链表  
双向链表 vs 动态数组
优缺点对比:
- 动态数组:开辟、销毁内存空间的次数相对较少,但可能造成内存空间浪费(可以通过缩容解决)
 - 双向链表:开辟、销毁内存空间的次数相对较多,但不会造成内存空间的浪费
 
如何应用:
- 如果频繁在尾部进行添加、 删除操作, 动态数组、 双向链表均可选择
 - 如果频繁在头部进行添加、 删除操作,建议选择使用双向链表
 - 如果有频繁的(在任意位置) 添加、 删除操作,建议选择使用双向链表
 - 如果有频繁的查询操作(随机访问操作),建议选择使用动态数组
 
作业与练习
练习 – 删除链表中的节点
https://leetcode-cn.com/problems/delete-node-in-a-linked-list/

练习 – 反转一个链表
https://leetcode.cn/problems/reverse-linked-list/

练习 – 判断一个链表是否有环
https://leetcode-cn.com/problems/linked-list-cycle/

作业

