Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用递归的反向双链表_Java_Algorithm_Recursion - Fatal编程技术网

Java 使用递归的反向双链表

Java 使用递归的反向双链表,java,algorithm,recursion,Java,Algorithm,Recursion,我正在编写程序,使用递归反转双链表。 我知道如何迭代实现。但是陷入了递归 这是我的 public static Node reverseRecurseDoubleLinkedList(Node node){ if (node==null || node.next==null) return node; Node newNode = reverseRecurseDoubleLinkedList(node.next); node

我正在编写程序,使用递归反转双链表。 我知道如何迭代实现。但是陷入了递归

这是我的

public static Node reverseRecurseDoubleLinkedList(Node node){
        if (node==null || node.next==null)
            return node;
        Node newNode = reverseRecurseDoubleLinkedList(node.next);
        node.next.next=node;
        node.next=null;
        node.prev=newNode;
        return newNode;
    }
我发现
prev
指针设置不正确。但是
next
指针实际上是正确的


一般来说,简化递归代码思想的一种方法是只考虑递归调用完成时所提供的保证。然后,您需要检查这些保证是否在停止递归的基本情况下有效(例如,空列表或具有单个节点的列表),并且它们是否在每次额外的递归调用中得到维护

提供的代码中有几个问题:

  • 停止递归的条件没有正确处理
    node.next==null
    时的情况。在这种情况下,
    node.prev
    字段应设置为
    null

  • newNode
    变量名可能会引起一些混淆。它表示反向列表的新头部(初始列表的尾部)。我把它重命名为
    newHead

  • 与上述点相关的赋值
    node.prev=newNode
    不正确--我们不希望每个节点的
    prev
    指向新列表的头部

合并这些方面后,下面的代码正确地颠倒了列表:

public static Node reverseRecurseDoubleLinkedList(Node node) {
    if (node == null) {
        return node;
    }

    if (node.next == null) {
        node.prev = null;
        return node;
    }

    Node newHead = reverseRecurseDoubleLinkedList(node.next);
    node.next.next = node;
    node.prev = node.next;
    node.next = null;

    return newHead;
}

一般来说,简化递归代码思想的一种方法是只考虑递归调用完成时提供的保证。然后,您需要检查这些保证是否在停止递归的基本情况下有效(例如,空列表或具有单个节点的列表),并且它们是否在每次额外的递归调用中得到维护

提供的代码中有几个问题:

  • 停止递归的条件没有正确处理
    node.next==null
    时的情况。在这种情况下,
    node.prev
    字段应设置为
    null

  • newNode
    变量名可能会引起一些混淆。它表示反向列表的新头部(初始列表的尾部)。我把它重命名为
    newHead

  • 与上述点相关的赋值
    node.prev=newNode
    不正确--我们不希望每个节点的
    prev
    指向新列表的头部

合并这些方面后,下面的代码正确地颠倒了列表:

public static Node reverseRecurseDoubleLinkedList(Node node) {
    if (node == null) {
        return node;
    }

    if (node.next == null) {
        node.prev = null;
        return node;
    }

    Node newHead = reverseRecurseDoubleLinkedList(node.next);
    node.next.next = node;
    node.prev = node.next;
    node.next = null;

    return newHead;
}

可能与@DuyAnhPham的问题相同:不,不是。我要的是双链接列表,请先阅读问题。反转双链接列表没有任何意义……您可以只交换头和尾引用。@Rugal:仅交换头和尾是不够的,由于未正确设置每个节点的
下一个
上一个
成员。可能与@DuyAnhPham的问题相同:不,不是。我要的是双链接列表,请先阅读问题。撤销双链接列表没有任何意义……您可以只交换头和尾引用。@Rugal:仅交换头和尾是不够的,因为每个节点的
next
prev
成员将无法正确设置。