目录
单向链表
每个元素只知道自己的下一个元素是谁,最后一个元素的下一个元素为null
初始
public class SingleLinkedList {
// 头指针
private Node head;
// 节点类 private对外隐藏细节
@Data
@AllArgsConstructor
private static class Node {
private int value;
private Node next;
}
}
将内部类定义为静态主要有两个原因:
- 实例化方式:静态内部类的实例化不需要依赖于外部类。而普通的内部类在实例化时会隐含地包含一个对外部类的引用,因此,普通的非静态内部类不能脱离外部类实例而单独存在。
- 访问方式:静态内部类可以使用静态方法直接通过类名来访问外部类的静态成员,而不需要创建外部类的实例。而普通的内部类需要先创建外部类的实例,然后通过该实例来访问外部类的静态成员。
头插
思路
对于使用者来说,我给你一个value值,你要将我的这个value值放入到链表头结点处
情况一
一开始,无节点,现在新增一个新节点
head = new Node(value, null);
情况二
一开始,有节点,现在新增一个新节点
head = new Node(value, head);
新节点的next指针指向原来节点,原来节点地址为头指针指向的地址
代码
public void addFirst(int value) {
head = new Node(value, head);
}
为什么没有情况一?
开始时,head为null,情况二包含情况一
尾插
思路
对于使用者来说,我给你一个value值,你要将我的这个value值放入到链表最后面
那我怎么知道你链表什么时候是最后面?
遍历
遍历到最后一个节点,此时它的next指针指向null
注意:头指针是为了记录第一个节点地址,不能动,所以我定义一个可以移动的指针开始指向第一个节点
public void foreach() {
Node p = head;
while (p != null) {
System.out.println(p.value);
p = p.next;
}
}
优化遍历
实际开发中,你可能不是要打印,而是对加进来的值有其他操作,此时,换成函数式编程
public void foreach(Consumer<Integer> consumer) {
Node p =