繁体   English   中英

通过更改连接从单链表转换为双链表

[英]Transforming from singly linked list to doubly by changing the connections

我有一个doubly linked list ,它模拟了singly linked list的行为。 所以我有一个left,right和info,但是left始终为null。 像这样:

1 -> 2 -> 3 -> 4

我想要的是仅通过解析列表并重新建立连接,即可将其重新更改为双倍而无需重新创建节点。

1 -> <- 2 -><- 3 -><- 4

我有

class Node {
    private int info;
    private Node left;
    private Node right;

而我的方法:

static Node toDoublyLinked(Node root) {
        if (root.getRight() != null) {
            root.getRight().setLeft(root);
            return toDoublyLinked(root.getRight());
        }
        return root;
    }

这不起作用。 它使我的程序抛出堆栈溢出,因为当我将2连接到1时,1已经连接到2-> 3-> 4,因此它将开始重复该列表,而这并不是我想要的。

有解决方案吗?

void add(int info) {
        Node s = new Node();
        if (this.info == 0) {
            this.info = info;
        } else {
            if (info < this.info) {
                if (left != null) {
                    left.add(info);
                } else {
                    s.setInfo(info);
                    this.left = s;
                }
            } else {
                if (right != null) {
                    right.add(info);
                } else {
                    s.setInfo(info);
                    this.right = s;
                }
            }
        }
    }

    public int getInfo() {
        return info;
    }

    public void setInfo(int info) {
        this.info = info;
    }

    public Node getLeft() {
        return left;
    }

    public void setLeft(Node left) {
        this.left = left;
    }

    public Node getRight() {
        return right;
    }

    public void setRight(Node right) {
        this.right = right;
    }

    @Override
    public String toString() {
        return "Node{" +
                "info=" + info +
                ", left=" + left +
                ", right=" + right +
                '}';
    }

好了,在进行了一些调试之后,似乎它确实在toDoublyLinked中但在toString方法中抛出了StackOverflow。 为什么甚至在该方法中调用toString? 我不是。 至少没有明确说明。 我可以理解为什么toString制作错误,但是即使我发表评论,它仍然无法正常工作。

public static void toDoublyLinked(Node node) {
    Node current = node;
    while (current.getRight() != null) {
        current.getRight().setLeft(current);
        current = current.getRight();
    }
}

如果要递归:

public static void toDoublyLinked(Node node) {
    if (node.getRight() != null) {
         node.getRight().setLeft(node);
         toDoublyLinked(node.getRight());
    }
}

但是请记住,就像我之前说的那样,由于Java没有尾部递归优化,即使在技术和意识形态上是正确的,WILL堆栈也会在长列表上溢出。

您不应使用会导致长列表上的堆栈溢出的递归。 相反,您应该使用迭代方法,例如:

public static void toDoublyLinked(Node node){
    Node currentNode = node ;
    while(currentNode.getRight() !=null){
         currentNode.getRight().setLeft(currentNode);
         currentNode = currentNode.getRight();
    }
}

这样,无论列表的长度如何,您的代码都不会导致堆栈溢出。 当然,您还有其他变量,但是可以避免长列表导致堆栈溢出并提高复杂性(调用函数的成本更高)。

但是,如果您仍然只想使用递归(尽管不应这样做),则下面是一段代码:

public static void toDoublyLinked(Node node) {
    if (node.getRight() != null) {
         node.getRight().setLeft(node);
         toDoublyLinked(node.getRight());
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM