单链表反转

第一种解法:建立虚拟头结点

 

public NodeList reversList(NodeList head){
       NodeList ans =new NodeList(-1);
       NodeList cur = head;
       while (cur!=null){
           //首先保存next不然后面就找不到了
           NodeList next = cur.next;
           //第一步,先把head接到ans的后面,相当于在ans和ans.next中间插入一个head,
           //所以cur才指向ans的next
           cur.next=ans.next;
           //然后再ans指向cur就可以辣
           ans.next=cur;
           //重定向cur
           cur=next;
       }
        return ans.next;
    }

想象一下,刚开始的时候虚拟头结点和虚拟头结点的next节点是两个节点,我们需要做的是把目标节点一个一个放在虚拟头结点的后面,首先目标节点要先指向ans.next,然后ans指向cur目标节点,这样下来,目标节点就成功插入进去了,进而取代它原本的ans.next成为了新的ans.next节点,而目标链表损失一个节点,它的一个节点就成为下次循环的目标节点,我们也只关注ans和ans.next和目标节点cur就可以了

第二种解法:直接操作链表

image.png

 

public NodeList reversList(NodeList head){
        NodeList pre =null;
        NodeList cur = head;
        while (cur!=null){
            //本来是head的cur的现在变成末尾,末尾呢指向pre,刚开始为null,cur和pre都要向后移,
            // 下一个cur必然要指向上一个cur,pre就是指向上一个cur的节点
            NodeList next = cur.next;
            cur.next = pre;
            pre=cur;
            cur=next;
        }
        return pre;
    }

这里要虚拟出一个pre节点,目标节点要从头开始一个个断开,第一个断开指向pre,然后pre向前移动,现在的pre就是第一个断开的节点,请记住,pre节点就是用来被断开的节点指向的,断开之后就会被下一个节点指向,所以就从指向别人变成了被指向,就实现了反转了。

第三种解法:递归

public NodeList reversList2(NodeList head){
        if (head==null||head.next==null){
            return head;
        }
        NodeList newHead = reversList2(head.next);
        head.next.next = head;
        head.next=null;
        return newHead;
    }

这个我认为理解的难点在于

head.next.next = head;

这句话的目的是反转head的指向,由指向别人变成被别人指向,假设原始链表是1 -> 2 -> 3 -> 4 -> 5那么递归结束的条件是head=5,head=5就是上一步的结果newHead,上一步的head就是4,假设head的next节点是nextHead节点,那么正常的逻辑应该是head.next=nextHead;要实现反转就是要next要指向head,就是next的下一个节点是head,nextHead.next =head,也就是head.next.next=head成立。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值