[TOC]
# 线性结构
![](https://box.kancloud.cn/8253f89d7e4fcbe7063c1a1a9bd7dac1_917x484.png)
链表Linked List
数据存储在节点(node)中
* 最简单的动态数据结构
* 深入的理解引用(或者指针)
* 深入的理解递归
~~~
class Node {
E e; //存放的元素
Node next; //指向下个元素
}
~~~
最后一个元素是指向null
![](https://box.kancloud.cn/41927c24479bd2a6ad1c39b5a1466b17_1098x252.png)
优点:真正的动态,不需要处理固定容量的问题
缺点:丧失了随机访问的能力,不能像数组那样给个索引就能访问
# 数组和链表的对比
* 数组最好用于索引有语意的情况.`scores[2]`
* 最大的有点:支持快速查询
* 链表不适合用于索引有语义的情况
* 最大的优点:动态
# 添加元素
## 链表头添加
![](https://box.kancloud.cn/d1df72318c4f2d23b5be3c23c0c81b24_1340x369.png)
~~~
node.next = head
head = node
~~~
## 链表中间添加元素
![](https://box.kancloud.cn/aedac82658ef88fba85300e4c5667fe4_1154x542.png)
找到要添加的节点是前一个节点
但是头部是没有前一个节点的
还有顺序很重要
<br>
如果我们这样写
~~~
prev.next = node
node.next = prev.next
~~~
node就指向自己了,就不对了
## 为链表设立虚拟头节点
![](https://box.kancloud.cn/e0a70706d77ca3028281781bf7166f9f_1335x275.png)
这样有了虚拟节点,我们在添加头部就不需要特殊处理了,这样每个元素都有头节点了
# 删除元素
![](https://box.kancloud.cn/a6c793049089345fca2a1c49f5b14265_1294x413.png)
还要为了能被gc,delNode要把他置为null
~~~
prev.next = delNode.next
~~~