文章目录
1. 双向链表
前面提到了单向链表,单链表的特点是只能从前向后遍历,但是如果我们已知一个节点在链表靠后的位置,这时如果使用单链表效率就会很低,因此引入了双向链表就可以快速的找到靠后的节点。双向链表与单向链表的区别就是它不仅有后继节点,还有前驱节点。这样就既存储了下一个节点的地址,也存储了前一个节点的地址。
2. 双向链表的定义
节点类:
class DoubleNode {
// 指向前驱节点
DoubleNode prev;
// 具体存储的数据
int val;
// 指向后继节点
DoubleNode next;
public DoubleNode(int val) {
this.val = val;
}
}
链表类:
public class DoubleLinkedList {
// 实际存储元素个数
int size;
// 双向链表的头节点
private DoubleNode first;
// 双向链表的尾节点
private DoubleNode last;
}
3. 增加操作
3.1 头插法
// 头插法
public void addFirst(int val) {
// 暂存头节点
DoubleNode head = first;
// 1.先 new 一个节点
DoubleNode node = new DoubleNode(val);
// 2.再将头节点指向新插入的节点
first = node;
// 注意判空
if (head == null) {
// 如果链表为空,尾节点就是头节点
last = node;
} else {
// 3.将新节点的后继与原来的第一个元素相连,再将原来第一个节点的前驱与新节点相连
node.next = head;
head.prev = node;
}
size++;
}
断点调试:
图解链表不为空时:
3.2 尾插法
// 尾插法
public void addLast(int val) {
DoubleNode l = last;
DoubleNode node = new DoubleNode(val);
last = node;
// 注意判空
if (l == null) {
// 头节点就是尾节点
first = node;
} else {
node.prev = l;
l.next = node;