目录
1. ArrayList的缺陷
上节课已经熟悉了
ArrayList
的使用,并且进行了简单模拟实现。通过源码知道,
ArrayList
底层使用数组来存储元素:
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
// ...
// 默认容量是10
private static final int DEFAULT_CAPACITY = 10;
//...
// 数组:用来存储元素
transient Object[] elementData; // non-private to simplify nested class access
// 有效元素个数
private int size;
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
// ...}
由于其底层是一段连续空间,当
在
ArrayList
任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后
搬移,时间复杂度为
O(n)
,效率比较低,因此
ArrayList
不适合做任意位置插入和删除比较多的场景
。因此:
java集合中又引入了LinkedList
,即链表结构。
2. 链表
2.1 链表的概念及结构
链表是一种
物理存储结构上非连续
存储结构,数据元素的
逻辑顺序
是通过链表中的
引用链接
次序实现的 。


链表是由一个个结点组成,而这些结点又是由数据域和next域构成(双向链表还会多一个prev域)
其中,data域存放数据,next域存放下一个结点的地址(prev域则存放前一个结点的地址)。
什么是“头”?
“头”,就是头节点的意思,它的组成如图:
头节点的data域是不存放元素的。
2.2 链表结构
实际中链表的结构非常多样,以下情况组合起来就有
8
种链表结构:
1.
单向或者双向

2.
带头或者不带头

3.
循环或者非循环

怎么从第一个节点走向第二个节点?head=head.next;链表什么时候遍历完?尾指针为空
虽然有这么多的链表的结构,但是我们重点掌握两种
: