请问两个传参不同,为什么结果不同(反转单链表)

问题遇到的现象和发生背景

反转链表reverseList函数传入head节点和传入a1节点,返回值不同;传入head可以正常返回反转链表,传入a1则不能

问题相关代码,请勿粘贴截图
class ListNode {
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) { this.val = val; }
    ListNode(int val, ListNode next) { this.val = val; this.next = next; }

    @Override
    public String toString() {
        return "ListNode{" + "val=" + val +"}";
    }
}

public class Solution {
    private static ListNode head= new ListNode(0);
    public static void main(String[] args) {
        ListNode a4=new ListNode(4,null);
        ListNode a3=new ListNode(3,a4);
        ListNode a2=new ListNode(2,a3);
        ListNode a1=new ListNode(1,a2);
        head.next=a1;
        while(a1!=null){
            System.out.println(a1.toString());
            a1=a1.next;
        }

//        ListNode a1=new ListNode(1);
//        ListNode a2=new ListNode(2);
//        ListNode a3=new ListNode(3);
//        ListNode a4=new ListNode(4);
//        a1.next=a2;
//        a2.next=a3;
//        a3.next=a4;
//        a4.next=null;
//        while (a1 != null) {
//            System.out.println(a1.toString());
//            a1 = a1.next;
//        }
        System.out.println("逆转");
        reverseList(a1);

        while (a4.next!=null) {
            System.out.println(a4.toString());
            a4 = a4.next;
        }
    }

    public static ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode p = reverseList(head.next);
        head.next.next = head;
        //System.out.println(p);
        head.next = null;
        //System.out.println(p);
        return p;
    }
}



运行结果及报错内容

传入head可以正常显示反转链表

img

传入a1就不能正常输出反转链表了

img

我的解答思路和尝试过的方法
我想要达到的结果

我觉得有没有头的链表应该都能被反转才对,为什么没头时传入第一个节点就不能显示反转链表?


        while(a1!=null){
            System.out.println(a1.toString());
            a1=a1.next;
        }
reverseList(a1);

a1经过循环已经是null了,传入null等于啥都不做。所以没效果。
不过即使你把reverseList(a1); 改成reverseList(head.next);
最终打印的也只是 4 3 2,问题出在循环条件
a4.next!=null
这个上面,循环到a1的时候,a1的next是null 所以就不打印a1的值了。
那效果就是虽然列表是反转了,但是打印是错的。可以把这个条件改成a4 != null

综上,一共有两个问题:

  1. 循环赋值的时候重新申请变量,不要用原来的a1,a4 用current/cur这种临时变量比较合理。
  2. 传入的时候,如果传a1,那么打印的循环条件也要改成a4!=null
class Solution {

    public static void main(String[] args) {
        ListNode a4 = new ListNode(4, null);
        ListNode a3 = new ListNode(3, a4);
        ListNode a2 = new ListNode(2, a3);
        ListNode a1 = new ListNode(1, a2);
        ListNode head = new ListNode(0, a1);
        printHeadList(head);

        System.out.println("--printNoHeadList--");
        // 你应该用这个方法的返回值,而不是直接用a4, 因为你不一定能持有原来列表的最后一个节点的引用
        ListNode newHead = reverseList(head.next);
        printNoHeadList(newHead);
        System.out.println("--printHeadList--");
        // 重新设为带有头结点的列表
        head.next = newHead;
        printHeadList(head);
    }

    public static void printHeadList(ListNode head) {
        ListNode cur = head.next;
        while (cur != null) {
            System.out.println(cur.toString());
            cur = cur.next;
        }
    }

    public static void printNoHeadList(ListNode head) {
        ListNode cur = head;
        while (cur != null) {
            System.out.println(cur.toString());
            cur = cur.next;
        }
    }

    public static ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode p = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return p;
    }
}

你这程序我运行了一下,现在貌似也不太正确啊,输出以下几行:
ListNode{val=1}
ListNode{val=2}
ListNode{val=3}
ListNode{val=4}
逆转
然后就没有了,然后就是单向链表应该只有从头节点开始才能遍历到尾节点,你给个中间的节点自然是无法反转的,除非你是双向链表

自己打个断点调试一下不就知道了么,还有你这递归的性能很差