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

算法通关村系列文章目录



前言

本系列文章是针对于鱼皮知识星球——编程导航中的算法通关村中的算法进行归纳和总结。 该篇文章讲解的是第二关中的青铜挑战———手写链表反转

链表反转无非是将每一个节点的指向反向,考虑的核心无非就一个

反向后,节点原来连接的其他节点如何处理

经典的链表反转方法有头插法和直接反向法


一、直接反转法

直接反转法其实就是将每一个节点的指向反转。

  1. cur–指向的是正在处理的节点
  2. pre–指向的是已反转链表的第一个节点,也是前一个完成反转的节点
  3. temp–指向的是下一个要反转的节点

在每一个节点的反转过程中,需要进行的操作

  1. 用temp保留cur链接的节点
  2. 让cur的next指向prev节点
  3. 将cur节点赋值给pre节点
  4. 将temp节点赋值给cur节点

  1. 先让 temp保留 cur链接的节点 是因为,最后反转的时候,是要将 cur的next指向prev的,如果不事先保存,直接指向会导致cur链接的节点丢失。
  2. 上面的步骤3和步骤4的顺序是不能反着来的,如果先将temp节点赋值给cur节点,那此时cur节点就不再指向的是这个刚刚完成反转的节点,而是下一个将要反转的节点,这个节点是没有链接到已反转的链表上的。

在这里插入图片描述
转换为代码

这里其实是直接从第二个节点进行反转了,所以这里要事先将 head.next=null; 否则后面 head仍然会链接到第二个节点,成为一个环。

        ListNode current=head.next;
        ListNode pre=head;
        head.next=null;
        while (current!=null){
            // 将要处理的节点后面的链表存起来
            ListNode temp=current.next;
            // 还是将要处理的节点连接到反转的链表的头部
            current.next=pre;
            pre=current;
            current=temp;
        }
        return pre;


二、建立虚拟头节点辅助反转-----头插法

在直接反转法中,我们是直接将原来的链表反转。
而头插法是新建立一个链表,然后将原链表的节点一个一个的摘下放到新建链表中

  1. cur—与直接插入法中的cur一致,仍然代表正在处理的节点
  2. ans—虚拟头节点,其携带的值无意义,只用来处理节点的反转

在头插法的反转过程中

ans的 next 永远指向已反转的链表的第一个节点

  1. 用temp保留cur链接的节点
  2. 将cur的next指向ans的next指向的节点
  3. 将ans的next指向现在的cur节点
  4. 将temp节点赋值给cur节点
    在这里插入图片描述
  1. 因为ans.next永远指向的是已反转链表的首个节点,所以将cur的next指向ans的next指向的节点就是将原来链表的节点摘出来添加到已反转链表的头部
  2. 将ans的next指向现在的cur节点就是重新让ans指向已反转链表的头部

转换为代码

        // 虚拟头节点 这里的-1就代表 这个节点携带的信息是不需考虑的
        ListNode virtual=new ListNode(-1);
        virtual.next=head;
        // 当前节点
        ListNode current = head.next;
        // 反转后 将首节点后面的连接取消掉
        head.next=null;
        ListNode temp = null;
        while (current != null) {
            // 先把要处理节点的后一个节点存起来
            temp = current.next;
            // 将要处理节点连接到反转链表的头部
            current.next = virtual.next;
            // 虚拟头节点连接到最新的反转链表的头节点
            virtual.next = current;
            // current节点往后移动
            current = temp;
        }

        return virtual.next;

总结

当了解完两个方法后,我们会发现其实两种方法的思想是一致的,都是先保存 cur节点的下一个节点,然后链接
之后将 头节点或者 pre再重新进行重置。简单总结就是 保存资源,反转链接,重置状态
其实链表反转的方法不止这两种,还有递归等方法。这些方法我们在后面的闯关中说明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值