数据结构之链表

链表

特点:
节点内部包含指向下一个节点的指针,这种称为单链表
既有下个节点也有上个节点的指针,这种称为双向链表

链表又分为带头结点和不带头结点的

链表的一些基本套路

假设链表为如下数据结构:

class ListNode {
    int val;
    ListNode next;
    public ListNode() {}
    public ListNode(int val) {this.val = val;}
}

快慢指针

所谓快慢指针,就是快指针每次移动两个节点,慢指针每次移动一个节点。
经常用于寻找一个链表的中间节点。
或者判断链表是否有环

public ListNode getMid(ListNode head) {
    ListNode fast = head, slow = head;
    while (fast != null && fast.next != null) {
        fast = fast.next.next;
        slow = slow.next;
    }
    return slow;
}

反转链表

反转链表,链表操作的入门级题目了。
主要是理解指向操作。
比如下面代码中的pre = cur;不是单纯地赋值操作。可以理解成pre指向cur节点。
动图表示就是pre指针往后移动了一位,指向了cur。我不会画动图,网上有可以看看。
指向操作可以说是理解链表的基础。这一题也要好好理解。

public ListNode reverse(ListNode node) {
    ListNode cur = head, pre = null;
    while (cur != null) {
        ListNode next = cur.next;
        cur.next = pre;
        pre = cur;
        cur = next;
    }
    return pre;
}

合并有序链表

也是入门级别的操作了。其中引入了dummyHead是解决很多链表问题的常用套路。
合并有序链表也是解决很多链表问题的步骤之一。比如链表排序。

public ListNode merge(ListNode l1, ListNode l2) {
    ListNode dummyHead = new ListNode(1);
    ListNode cur = dummyHead;
    while (l1 != null && l2 != null) {
        if (l1.val < l2.val) {
            cur.next = l1;
            l1 = l1.next;
        } else {
            cur.next = l2;
            l2 = l2.next;
        }
        cur = cur.next;
    }
    cur.next = l1 == null ? l2 : l1;
    return dummyHead.next;
}
posted @ 2022-06-29 13:04  cfdroid  阅读(31)  评论(0编辑  收藏  举报