MyLinkedList.java
/**
* 双向链表
* 对外提供CRUD
*
* 链表索引起点:0
*/
class MyLinkedList {
private Node head; // 头结点,可变化。管理链表的核心。
private Node tail; // 尾节点的引用。
private int size; // 链表节点的个数
// 初始化
public MyLinkedList() {
head = new Node<>(null, null, null);
tail = head;
// head只有next会变
// tail只有pre会变
size = 0;
}
private boolean isNull() {
return head == tail;
}
private void checkIndex(int pos) {
if (pos >= size) {
throw new RuntimeException("查询失败,越界的pos值:" + pos);
}
}
// 遍历打印
@Override
public String toString() {
// head不打印
// if ! isNull printn(tail) else 不打印
if (isNull()) {
return "0 []";
}
StringBuilder sb = new StringBuilder(String.format("%d [", size));
for (Node it = head.next; it.next != null; it = it.next) {
sb.append(String.format("%s, ", it.data));
}
sb.append(String.format("%s]", tail.data));
return sb.toString();
}
// 尾部追加
public void append(T element) {
// 分第一次和其他次
if (tail.pre != null) {
// System.out.println("并非第一次追加");
Node node = new Node<>(tail, element, null); // 新节点指向尾节点
tail.next = node; // 尾节点指向新节点
tail = node; // 设置新的尾节点
} else {
// System.out.println("第一次追加");
Node node = new Node<>(head, element, null); // 新节点指向第一个head
head.next = node; // 设置head的下一个是node
tail = node; // 设置新的tail
}
size++;
}
// 修改
public void set(int pos, T element) {
checkIndex(pos);
Node it = head.next; // iterator
for (int i = 0; i < pos; i++) {
it = it.next;
}
it.data = element;
}
// 查询
public T get(int pos) {
checkIndex(pos);
Node it = head.next;
for (int i = 0; i < pos; i++) {
it = it.next;
}
return it.data;
}
// 插入
public void insert(int pos, T element) {
checkIndex(pos);
Node it = head.next; // iterator
for (int i = 0; i < pos; i++) {
it = it.next;
}
// it指向了要挪窝的节点
Node node = new Node<>(it.pre, element, it); // 新节点指向前后节点
it.pre.next = node; // it的前置节点的下一个节点不指it,改为指向node。
it.pre = node; // it的前置节点改为node
size++;
}
// 删除
public T delete(int pos) {
checkIndex(pos);
Node it = head.next;
for (int i = 0; i < pos; i++) {
it = it.next;
}
// it指向了要删除的节点。前后节点忽略IT。
it.pre.next = it.next;
it.next.pre = it.pre;
T tmp = it.data;
it = null;
size--;
return tmp;
}
}
测试
public static void main(String[] args) {
MyLinkedList list = new MyLinkedList<>();
System.out.println(list);
list.append(123);
System.out.println(list);
list.append(456);
System.out.println(list);
list.append(789);
list.append(1);
list.append(2);
System.out.println(list);
list.set(0, 111); // pos 属于 [0, pos]
System.out.println(list.size - 1);
list.set(list.size - 1, 666);
System.out.println(list);
list.insert(3, 999999);
System.out.println(list);
list.insert(3, 8888);
System.out.println(list);
System.out.println(list.get(0));
System.out.println(list.get(list.size - 1));
System.out.println(list);
System.out.println(list.delete(3));
System.out.println(list);
}
输出
0 []
1 [123]
2 [123, 456]
5 [123, 456, 789, 1, 2]
4
5 [111, 456, 789, 1, 666]
6 [111, 456, 789, 999999, 1, 666]
7 [111, 456, 789, 8888, 999999, 1, 666]
111
666
7 [111, 456, 789, 8888, 999999, 1, 666]
8888
6 [111, 456, 789, 999999, 1, 666]