双向链表是一种特殊链表,每个节点包含两个指针
,一个指向前一个节点,一个指向后一个节点。双向链表可以支持双向遍历,插入和删除操作更加高效。双向链表的基本操作包括插入、删除、查找等。
双向链表的常见应用场景包括LRU缓存淘汰算法
、双向队列
等需要频繁在两端进行操作的场景。
下面我们手写一个双向链表来看看它的用法。
代码如下:
1. 定义双向链表节点类
class ListNode {
int val;
ListNode prev;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
2. 定义双向链表类
class MyDoublyLinkedList {
private ListNode head;
private ListNode tail;
public MyDoublyLinkedList() {
this.head = null;
this.tail = null;
}
public void addAtHead(int val) {
ListNode newNode = new ListNode(val);
if (head == null) {
head = newNode;
tail = newNode;
} else {
newNode.next = head;
head.prev = newNode;
head = newNode;
}
}
public void addAtTail(int val) {
ListNode newNode = new ListNode(val);
if (tail == null) {
head = newNode;
tail = newNode;
} else {
tail.next = newNode;
newNode.prev = tail;
tail = newNode;
}
}
public void addAtIndex(int index, int val) {
ListNode newNode = new ListNode(val);
if (index <= 0) {
addAtHead(val);
} else if (index >= size()) {
addAtTail(val);
} else {
ListNode current = head;
for (int i = 0; i < index - 1; i++) {
current = current.next;
}
newNode.next = current.next;
current.next.prev = newNode;
current.next = newNode;
newNode.prev = current;
}
}
public void deleteAtIndex(int index) {
if (index < 0 || index >= size()) {
return;
}
if (index == 0) {
head = head.next;
if (head != null) {
head.prev = null;
} else {
tail = null;
}
} else {
ListNode current = head;
for (int i = 0; i < index; i++) {
current = current.next;
}
current.prev.next = current.next;
if (current.next != null) {
current.next.prev = current.prev;
} else {
tail = current.prev;
}
}
}
public int get(int index) {
if (index < 0 || index >= size()) {
return -1;
}
ListNode current = head;
for (int i = 0; i < index; i++) {
current = current.next;
}
return current.val;
}
}
3. 测试双向链表
public class Main {
public static void main(String[] args) {
MyDoublyLinkedList dll = new MyDoublyLinkedList();
dll.addAtHead(1);
dll.addAtTail(3);
dll.addAtHead(2);
ListNode current = dll.head;
while (current != null) {
System.out.print(current.val + " ");
current = current.next;
}
System.out.println();
}
}