类属性
private Node head = null;
初始头结点为空
节点类
private static class Node {
private int value;
private Node next;
public Node(int value, Node next) {
this.next = next;
this.value = value;
}
}
节点类有两个属性:值 value 和指向下一个节点的指针 next
addFirst(int value)方法
public void addFirst(int value) {
if (head == null)
head = new Node(value, null);
else
head = new Node(value, head);
}
在链表头部插入元素,需要判断头结点是否为空
addLast(int value)方法
public void addLast(int value) {
if (head == null) {
addFirst(value);
return;
}
Node last = head;
while (last.next != null)
last = last.next;
last.next = new Node(value, null);
}
在链表尾部插入元素,需要判断头结点是否为空
注意循环遍历链表元素的方式
insert(int index, int value)方法
public void insert(int index, int value) {
if (index == 0) {
addFirst(value);
return;
}
Node prev = head;
for (int i = 0; prev != null; prev = prev.next, i++) {
if (index - 1 == i) {
break;
}
}
prev.next = new Node(value, prev.next);
}
注意,插入和删除都是找到上一个节点,输入的 index 要减1
remove(int index)方法
public void remove(int index) {
if (index == 0) {
if (this.head != null) {
this.head = this.head.next;
return;
} else {
throw new IllegalArgumentException();
}
}
Node prev = head;
for (int i = 0; prev != null; prev = prev.next, i++) {
if (index - 1 == i) {
break;
}
}
prev.next = prev.next.next;
}
单链表中,无论是添加还是删除,都要判断头结点是否为空,比较麻烦
而使用带有哨兵(sentinel)的单链表则可以很好地解决问题