簡體   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