[路飞]前端学链表_链表的翻转

147 阅读2分钟

「时光不负,创作不停,本文正在参加2021年终总结征文大赛

leetcode 反转链表

描述: 1 -> 2 -> 3 -> 4 -> 5 变成 5 -> 4 -> 3 -> 2 -> 1

思路:

  1. 当前指针是1的时候, 需要next 指向 null, 当前指针是 2 的时候 需要 next 指向前面已经反转的 1 -> null, 依次遍历单前指针指向下个节点 直到到尾结点
  2. 但是链表是空或者一个节点的时候反转还是本身

循环

function reverseList(head) {
    // 先判断是空或者一个节点
    if (head === null || head.next === null) return head
    
    // 记录当前指针
    let cur = head
    // 记录已经反转的链表,初始值是个空
    let prev = null
    // 记录下个节点
    let p = head.next
    // 逐个遍历
    while(cur) {
        // 当前指针的下个节点指向已经反转的链表
        cur.next = prev
        // 更新已反转的链表
        prev = cur
        // 需要遍历,变动当前指针, 变成下个节点
        cur = p
        // 然后变化下个节点 直到尾结点
        if(p) p = p.next
    }
    // 把反转的链表return
    return prev
}

递归

思路:

1. 1 -> 2 三个链表的时候, 我们需要怎么反转 
let head = {
    val: 1,
    next: {
        val: 2,
        next: null
    }
}

const tail = head.next
tail.next = head
head.next = null

// tail 就是我们的值 代表已反转的值

let head = {
    val: 1,
    next: {
        val: 2,
        next: {
            val: 3,
            next: null
        }
    }
}

const tail = head.next
const p = tail.next
head.next = null
tail.next = head
p.next = tail
// p代表反转的值 tail 相当于val:3 之前反转的值

function reverseList(head) {
    // 空或一个节点
    if(head === null || head.next === null) return head
    // 用tail 记录已经反转的节点
    let tail = head.next
    // 然后反转剩余节点 用p记录
    let p = reverseList(tail)
    // 反转第一个和第二个节点
    head.next = tail.next // 第一个节点的next 指向 tail.next
    tail.next = head // tail的next 指向head
    
    return p
}

总结

  • 反转链表 - 当前节点的变动和next指针指向的变动
  • 循环遍历可以用tmp保存cur.next的节点 不用记录p