【问题标题】:Recursively reversing a linkedlist [duplicate]递归反转链表[重复]
【发布时间】:2016-09-26 18:08:36
【问题描述】:

我正在尝试使用递归调用来反转 LinkedList,请让我知道我哪里出错了,我无法捕捉到反转的 LL 头。 LLNode 是链表节点,ReverseLLRecursively.reverse 是我写的逆向函数。

这是我的代码:

public class LLNode {
    private int data;
    private LLNode next;

    public LLNode(int data, LLNode next) {
        this.data = data;
        this.next = next;
    }

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public LLNode getNext() {
        return next;
    }

    public void setNext(LLNode next) {
        this.next = next;
    }

    @Override
    public String toString() {
        return data + "->[" + (next!=null?next.data:"") + "]";
    }
}

public class ReverseLLRecursively {

    public static LLNode newHead = new LLNode(-1, null);

    public static LLNode reverse(LLNode head, LLNode newHead) {
        if(head==null || head.getNext()==null) {
            newHead = head;
            return head;
        }

        LLNode node = reverse(head.getNext(), newHead);
        node.setNext(head);
        head.setNext(null);
        return node.getNext();
    }

    public static void main(String[] args) {
        LLNode ll = new LLNode(1,new LLNode(2, new LLNode(3,  new LLNode(3, new LLNode(2,  new LLNode(3, null))))));

        reverse(ll , newHead);
        System.out.println(newHead);

    }

}

【问题讨论】:

  • 我知道网络上有现成的解决方案可以递归地反转 LL。但这不会帮助我理解我在递归中哪里出错了。
  • 你试图做很多事情,结果却做错了事。你有两个机制。两者都不起作用。你只需要1,也就是reverse(ll)的returnValue;我的答案中有静态和非静态版本,将它们与您的进行比较并查看差异(尽管我的版本有点不言自明,因为它的名称正确)。还要学会正确命名东西,你所有的名字和变量都被滥用了,导致你不理解自己的代码。
  • 只需重命名您的方法变量: public static LLNode reverse(LLNode head, LLNode newHead) 然后 LLNode node = reverse(head.getNext(), newHead);这将起作用。
  • @Tunaki,我不是在寻找反转链接列表的解决方案,而是在我的方法中出现问题。为什么它仍然被标记为重复?

标签: java recursion singly-linked-list


【解决方案1】:

将反向作为 LLNode 的方法,使事情变得更容易。

您希望返回链接列表中的最后一个值(并且仅返回最后一个值)。如果你拥有它,就返回,否则深入到你拥有它为止。有了 end 后,存储它,setNext 不再需要 next 的值,返回 end。

public LLNode reverse(LLNode previous) {
    if(getNext()==null) {
        setNext(previous);
        return this;
    }
    LLNode returnValue = getNext().reverse(this);
    setNext(previous);
    return returnValue;
}

public static void main(String[] args) {
        LLNode ll = new LLNode(1,new LLNode(2, new LLNode(3,  new LLNode(3, new LLNode(2,  new LLNode(3, null))))));

        ll = ll.reverse(null);
        System.out.println(ll);

}

如果您出于任何原因需要它,则使用静态变体。

public static LLNode reverse(LLNode current) {
    if(current.getNext()==null) {
        return current;
    }
    LLNode returnValue = reverse(current.getNext());
    current.getNext().setNext(current);
    current.setNext(null);
    return returnValue;
}

public static void main(String[] args) {
        LLNode ll = new LLNode(1,new LLNode(2, new LLNode(3,  new LLNode(3, new LLNode(2,  new LLNode(3, null))))));

        ll = reverse(ll);
        System.out.println(ll);

}

【讨论】:

    【解决方案2】:

    您的问题过于复杂,并使用与静态成员同名的局部变量。这应该更简单:

    public static LLNode reverse(LLNode previous) {
        if(previous==null) {
            return null;
        }
        LLNode toReturn = (previous->getNext() == null) ? previous : reverse(previous.getNext());
        previous.getNext().setNext(previous);
        return toReturn;
    }
    

    注意,toReturn 将是新的头部。

    【讨论】:

    • 获取空指针异常。
    • @user2725673,是的,如果previous->getNext() 错误地为null 而不是previous,我返回了previous.getNext()。请再试一次。
    猜你喜欢
    • 1970-01-01
    • 2018-12-03
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    • 2012-11-05
    相关资源
    最近更新 更多