文章目录
前言
我们之前学的单链表,默认只能从链表的头部遍历到链表的尾部,在实际中应用太少见,太局限;而双向链表,对于该链表中的任意节点,既可以通过该节点向前遍历,也可以通过该节点向后遍历,双向链表在实际工程中应用非常广泛,是使用链表这个结构的首选。
一、认识双向链表
单向链表不仅保存了当前的结点值,还保存了下一个结点的地址
双向链表不仅保存了当前节点的值,还保存了上一个结点的地址和下一个结点的地址
定义一个双向链表的结点类
结点中既要保存当前节点的值,还要保存此节点的前驱节点的地址和此节点的后继节点的地址
class DoubleNode{
public DoubleNode next;
DoubleNode prev;
int val;
DoubleNode tail;
public DoubleNode() {
}
public DoubleNode(int val) {
this.val = val;
}
public DoubleNode(DoubleNode prev, int val, DoubleNode tail) {
this.prev = prev;
this.val = val;
this.tail = tail;
}
}
定义一个双向链表类
既可以从前向后,也可以从后向前,所以在这个类中,即保存一下头结点,也保存一下尾结点的值
public class DoubleLinkedList {
private int size;
private DoubleNode head;
private DoubleNode tail;
}
二、双向链表的增删改查
1.插入
1.头插
在当前链表的头部插入一个节点,让当前链表的头结点head前驱指向要插入的节点node,然后让node的后继指向head,然后让head = node,让node成为链表的头结点
代码如下:
/**
* 头插
*/
public void addFirst(int val){
DoubleNode node = new DoubleNode(val);
if (head == null){
head = tail = node;
}else{
node.next = head;
head.prev = node;
head = node;
}
size++;
}
2.尾插
和头插一样,只不过在链表的尾部插入
代码如下:
public void addLast(int val){
DoubleNode node = new DoubleNode(val);
if (head == null){
head = tail =node;
}else{
tail.next = node;
node.prev = tail;
tail = node;