算法通关村第二关——终于学会链表反转了

对于链表反转,我自己先想到的就是建立一个栈,因为栈是先进后出的一个数据结构,那我们遍历整个链表,把元素存储在栈当中,然后再创建一个链表放入元素就可以了,但是仔细想想运行内存和速度其实都比较慢,因为先开辟出了两个新的空间。

那对于新学的有很多方法

一、建立虚拟头结点辅助反转

public static ListNode reverseListByDummyNotCreate(ListNode head) {
        ListNode ans = new ListNode(-1);
        ListNode cur = head;
        while (cur != null) {
            ListNode next = cur.next;
            cur.next = ans.next;
            ans.next = cur;
            cur = next;
        }
        return ans.next;
    }

虚拟头结点呢,顾名思义就是建立一个虚拟的头结点,作为反转链表的头结点,再将旧链表当中的节点逐个放进新的链表当中。当中我自己最有异议的地方就是为什么要创建一个新的节点next来存放cur.next,实际上cur.next在下面的代码中变换了内容,把头结点的next赋给cur的next,然后将ans的next变为cur,这样就实现的了cur节点插入新的链表,这时要把cur进行移动,如果没有next这个节点,cur没有办法移动,这样我们next节点的作用就实现出来了。

二、直接操作链表实现反转

public static ListNode reverseListSimple(ListNode head) {
        ListNode prev = null;
        ListNode curr = head;
        while (curr != null) {
            ListNode next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        return prev;
    }

直接操作反转链表跟虚拟头结点,我个人认为两者之间的不同不是特别的大,而是用了虚拟头结点之后,代码会非常容易的理解。还是先把curr的next提取出来命名为next,然后把prev赋给curr。next,这里呢prev永远会在插入节点的后一个位置,再把curr赋给prev,这时就插入了第一个节点了,curr这个节点是代指远链表的第一个节点,老头结点走了,那就得赋给新的头结点。

我个人的见解是,虚拟头结点呢,是一直在头结点后面插入节点,对于链表来说这是非常好理解的,因为链表本就是一个有顺序的结构。而直接操作呢,是第一个节点前插入节点,一直在头部插入节点,思维更加的抽象,所以比较难想。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值