概念
与数组相似,链表 也是一种线性数据结构,链表中的每个元素(节点)都是一个单独的对象,可以存在内存中任何空闲的位置,元素之间通过引用字段来链接在一起,

如上图是一个简单的示例,链表中每个元素除了存储数据外还需要存储链接下一个元素引用,我们把存储数据的叫数据域,存储下一个元素的引用称为指针域,把链表的第一个节点叫头节点,最后一个节点叫尾节点,尾节点的指针域为null.
为什么会出现链表
由于顺序存储结构(数组)在内存中是一片连续空间,相邻元素之间没有空闲的位置,执行插入、删除操作需要移动大量元素,时间复杂度为O(n).
为了弥补顺序存储结构的不足,从而出现了链表,由于链表中的元素之间的关联关系是通过引用字段链接在一起的,元素之间不存在空间的依赖性,这样在执行插入和删除操作时,只需要修改元素的引用即可.
注意:链表中的元素可以存在内存中任何空闲位置,并不一定是连续的,也可以是这样的:

链表的种类

链表的操作
链表的操作基本和数组一样,包含添加、删除、修改、读取、获取链表的长度,这里我们仅仅以单链表来举例;链表中每个节点不仅包含值,还包含链接到下一个节点的引用字段,所以我们用一个Node类来表示节点:
class Node<E> {
// 当前节点的数据
E item;
// 下一个节点的引用
Node<E> next;
public Node(E item, Node<E> next) {
this.item = item;
this.next = next;
}
public Node() {}
}
添加操作
- 头插法:始终让新节点位于第一个位置
- 尾插法:始终让新节点位于最后一个位置

//头插法的关键代码
public void addAtHead(E e) {
//创建新节点
Node newNode=new Node(e);
//将新节点的下一个节点指向头节点
newNode.next=head;
//更新头节点,将head置为新节点
head=newNode;
}
//尾插法的关键代码
public void addAtTail(E e) {
//得到头节点
Node current=head;
//创建新节点
Node newNode=new Node(e);
//得到链表的最后一个节点
while(current.next!=null){
current=current.next;
}
//将最后一个节点的下一个节点置为新节点
current.next=newNode;
}
---- 待更新