美文网首页
2.1 单链表的反转

2.1 单链表的反转

作者: zzpwestlife | 来源:发表于2019-08-22 09:23 被阅读0次

当我们在聊到链表反转的时候,一定说的都是单链表,双链表本身就具有前驱指针 Prev 和后续指针 next,无需进行翻转。

栈实现的链表反转

在原本链表的数据结构之外,引入一个栈(数组也可),将单链表循环遍历,将所有结点入栈,最后再从栈中循环出栈,记住出栈的顺序,得到的就是反转后的单链表。

栈实现的链表反转

但是这样实现,有一个问题,它会额外消耗一个栈的内存空间,此时空间复杂度就变成了 O (n)。并且,栈会遇到的问题,使用此种方式都会遇到,例如比较常见的,栈的深度问题。

空间复杂度为 O(1) 单链表反转

接下来我们看看如何解决空间复杂度的问题。

在排序算法中,有一个概念叫原地排序,指的是不需要引入额外的存储空间,在原数据结构的基础上进行排序。这种排序算法的空间复杂度是 O(1)。例如我们常见的冒泡排序、插入排序都是原地排序算法。

这里,我们也可以在原单链表的数据结构上,进行单链表反转。

原地单链表反转,是一种很基础的算法,但是有一些在面试中遇到这道题,思路不清晰时,一时半会也写不出来。

容易出错的点在于,指针丢失。在转换结点指针的时候,所需结点和指针反转顺序,都很重要,一不小心,就会丢掉原本的后续指针 next,导致链表断裂。

迭代实现单链表反转

删除单链表的时候,需要知道前后三个结点。在单链表翻转的时候,也是这样。

当我们要对一个结点进行指针翻转的时候,我们也需要知道三个结点。

  • 待反转的结点。
  • 待反转结点的前驱结点 prev。
  • 待反转结点的后续结点 next。

说了那么多,直接上代码。(画出三个节点的单链表反转,就很容易理解了。就是不断地把头结点取下来,使其成为新链表的头结点)

static class Node {
    int data;
    Node next;

    Node(int data) {
        this.data = data;
    }
}

static Node reverseByLoop(Node head) {
    // 节点个数少于2,没必要反转
    if (head == null || head.next == null) {
        return head;
    }

    Node preNode = null;
    Node nextNode = null;
    while (head != null) {
        nextNode = head.next;
        head.next = preNode;
        preNode = head;
        head = nextNode;
    }
    return preNode;
}

此处以头结点为参数,反转之后返回值为反转后的单链表头结点。

递归实现单链表反转

单链表反转,还可以通过递归来实现,但是这里不推荐使用,大家了解一下就好了。

递归还是在借助函数调用栈的思想,其实本质上也是一个栈。没什么好说的,直接上代码。

static Node reverseByRecursion(Node head) {
    if(head == null || head.next == null) {
        return head;
    }

    Node newHead = reverseByRecursion(head.next);

    head.next.next = head;
    head.next = null;
    return newHead;
}

同样,画图能更好得理解,最难的就是 head.next.next = head

总结

这是一道经典面试题目,有很多细节需要仔细考虑,很容易忽视。用纸笔画出来,然后在脑子里能有一个动画,代码基本就没有问题的。(TODO 画图)

相关文章

  • 2.1 单链表的反转

    当我们在聊到链表反转的时候,一定说的都是单链表,双链表本身就具有前驱指针 Prev 和后续指针 next,无需进行...

  • Algorithm小白入门 -- 单链表

    单链表递归反转链表k个一组反转链表回文链表 1. 递归反转链表 单链表节点的结构如下: 1.1 递归反转整个单链表...

  • 单链表反转

    单链表 单链表反转 递归方法

  • 链表简单算法相关练习

    单链表反转: 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 迭代方式实现: 复杂度分析: 时...

  • Java、Python3 实战 LeetCode 高频面试之单链

    单链表反转 单链表反转这道题可谓是链表里面的高频问题了,差不多可以说只要被问到链表,就会问单链表反转。 今天我们就...

  • 5个链表的常见操作

    链表 链表反转 LeetCode206:给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 环路检...

  • 反转链表

    给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

  • 【教3妹学算法】2道链表类题目

    题目1:反转链表 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head ...

  • js+链表

    链表结构 删除链表某节点 遍历 反转单链表

  • 反转单链表

    题目:反转单链表。

网友评论

      本文标题:2.1 单链表的反转

      本文链接:https://www.haomeiwen.com/subject/bcygsctx.html