反转链表

方法一(最优) : 通过两个变量实现链表的反转,

技巧为:取值,反转,右移,拿值

取值是怕在反转的时候把 next 节点给弄丢了,所以先保存下一个节点的值

反转是核心步骤,即 (要反转的节点)head.next = pre(反转的方向);

右移是为了进行下一次的反转

拿值也算是右移,因为有两个变量,所以要两次右移

public ListNode ReverseList(ListNode head) {
    if(head == null) return null;
    ListNode cur = null;
    ListNode pre = null;
    while(head != null){
        cur = head.next;//取值
        head.next = pre;//反转
        pre = head;//右移
        head = cur;//拿值
    }
    //这时候head 跑到最后已经为null了,pre才是返回的
    return pre;
}

方法二(巧妙的递归反转)

巧就巧在 : head.next.next = head; 意思是,我的下一个的节点的下一个节点就是我, 假设 a -> b -> c,那从 b 开始,b.next 就是 c, 那我把c.next 赋为 b, 不就是巧妙的变成 a -> b <- c 了吗,但是还有一个步骤就是,必须把 b.nexy = null; 因为反转最后一个元素时,需要把null 赋给它的 next, 而 非尾节点会在下一次的反转中得到它的 next 节点,也就是箭头。

public ListNode ReverseList(ListNode head) {
    if(head == null || head.next == null) return head;//先定义退出条件,递归必须点
    ListNode cur = ReverseList(head.next);//递归操作,并保存每次操作的节点
    //倒数第二个节点在这里先执行
    head.next.next = head;//巧妙之处,  可以看做 (下一个节点) a = head.next    a.next = head(前一个节点)
    head.next = null;//必须点,得把他指向的箭头拆掉,等上一个继续反转,再付给他箭头
    return cur;
   
}

双链表的反转,需要两次反转,其他思路跟单链表一样

取值,反转,反转,右移,右移

public DoubleNode DoublereverseList(DoubleNode head){
    DoubleNode pre = null;
    DoubleNode next = null;
    while (head != null){
        next = head.next;//取值
        head.next = pre;//反转
        head.last = next;//反转,两次
        pre = head;//右移
        head = next;//右移
    }
    return pre;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容