编程导航算法通关村|第 1 关|青铜挑战

320 阅读2分钟

链表

笔记大纲

  • 什么是链表
  • 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
}

增加节点

链表的增操作按照新结点的位置不同作分为:

  • 头部节点增加
  • 中部节点增加
  • 尾部节点增加

头部增加

  1. new 新节点()
  2. 新节点.next = head
  3. head = 新节点

中部增加

在值为 X 的结点前插入一个新结点,那么指针在 X 结点前需要停下来,如果在 X 结点处停下来,那么单链表是不知道 X 结点前一个结点的地址,故循环体为:

while(cur.next != x){
    cur = cur.next;
}

当 cur 走到 X 的前一个节点时,while 中的判断语句为 false,cur 不会在执行循环体中的语句,停在 X 之前一个节点。

尾部增加

  1. new 新节点(),新节点.next == null
  2. 遍历链表,但是按照前文的遍历方法,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;