面试:反转链表

133 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

链表

与数组相似,链表也是一种 线性 数据结构

区别于数组,链表中的元素不是存储在内存中连续的一片区域,链表中的数据存储在每一个称之为「结点」复合区域里,在每一个结点除了存储数据以外,还保存了到下一个节点的指针(Pointer)。

它的每个元素都是一个单独的对象,所有的对象都是通过每个元素中的引用字段链接在一起的。

反转链表

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:

输入: 1->2->3->4->5->NULL

输出: 5->4->3->2->1->NULL

分析

单链表只能依次通过 next 访问,不能通过索引访问。

在遍历链表时,将当前节点的 cur.next 指针改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。

cur 当前项 prev 上一项 cur.next 当前指针指向

当前cur 的指针 next 指向 prev上一项 并且 交换迭代 prevnext

解法

迭代

var reverseList = function(head) {
    // 定义 cur 指向头部
    // pre 指向头部前面的null
    let prev = null, cur = head;
    // 遍历链表
    while (cur) {
        // 定义 temp 为cur下一个
        const temp = cur.next;
        // cu r的指向改为 pre
        cur.next = prev;
        // pre改为当前cur的指向
        prev = cur; // 把当前项
        // cur的指向改为 temp 的指向
        cur = temp;
    }
    // 遍历结束,cur指向null,返回 pre
    return prev
};

使用 ES6 结构解析

var reverseList = function(head) {
    let [p, c] = [null, head]
    
    while (c) [c.next, p, c] = [p, c, c.next]
    
    return p
};

递归

var reverseList = function(head) {
    if (head == null || head.next == null) return head
    const p = reverseList(head.next)
    head.next.next = head
    head.next = null
    return p
};

结语

如果这篇文章帮到了你,欢迎点赞👍和关注⭐️

文章如有错误之处,希望在评论区指正🙏🙏。

附: