链表
笔记大纲
- 什么是链表
- Java 中如何创建链表
- 链表的遍历
- 增删改查
什么是链表
每个元素的后继元素唯一的线性表
Java 中如何创建链表
一个结点可以视为以下类的一个实例:
public class ListNode {
public int val;
public ListNode next;
public ListNode() {}
public ListNode(int val) { this.val = val; }
public ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
遍历链表
将头节点地址传入,使用 while语句循环遍历,终止的条件是当前结点不为 null(why:与大脑遍历这个链表的逻辑相似,大脑在得知这个节点实际存在值(不为 null)时,才会计入遍历),每次循环体中打印(或计数)当前结点的 val,并移动当前指针。
该部分重点是不要移动 head 结点,需重新创建一个结点来模拟遍历,遍历完整个链表,他应该指向链表尾端的 next 域,即 null。
//查询链表长度
public static int lenOfLinkedList(ListNode head){
int length = 0;
ListNode myHead = head;
while (myHead != null){
length++;
myHead = myHead.next;
}
return length; //return 时,myHead 会指向 null
}
增加节点
链表的增操作按照新结点的位置不同作分为:
- 头部节点增加
- 中部节点增加
- 尾部节点增加
头部增加
- new 新节点()
- 新节点.next = head
- head = 新节点
中部增加
在值为 X 的结点前插入一个新结点,那么指针在 X 结点前需要停下来,如果在 X 结点处停下来,那么单链表是不知道 X 结点前一个结点的地址,故循环体为:
while(cur.next != x){
cur = cur.next;
}
当 cur 走到 X 的前一个节点时,while 中的判断语句为 false,cur 不会在执行循环体中的语句,停在 X 之前一个节点。
尾部增加
- new 新节点(),新节点.next == null
- 遍历链表,但是按照前文的遍历方法,cur 指针会走到 null,所以要将 while 中的条件改为:
//让 cur 走向链尾部(非 null)
public static NodeList gotoBottom(ListNode head){
ListNode cur = head;
while (cur.next != null){
cur = cur.next;
}
return cur; //return 时,cur 会指向 链末数据
}
3.cur.next = 新节点
删除节点
删除头节点
head = head.next, 原头节点会被垃圾回收
删除尾结点
要删除尾结点,实质是要断掉尾结点的前一节点指向尾结点的这条链,所以 cur 需要停在尾结点前一结点处,while 里的条件想必已经浮出水面了。然后执行:
cur.next = null;
删除中部结点
让 cur 指向需要删除节点的前一个结点,while 里的条件也已经总结过了。然后执行:
cur.next = cur.next.next;