BST到LinkList并返回到同一个BST

时间:2012-09-24 10:46:08

标签: algorithm binary-search-tree

由于我找不到任何有用的东西所以我在这里问我的问题:

我们如何将BST转换为有序链接列表,并返回“相同”BST,而不使用任何额外空间。

到目前为止我已尝试过(尽管如此):我尝试将Morris Traversal连接到下一个有序继任者, 但它无法连接所有节点,只能用于左子树和右子树,而不能用于树的实际根。 请建议如何将树转换为链接列表并返回到同一树...

5 个答案:

答案 0 :(得分:0)

要在列表中存储树 - 您至少需要两个列表:一个用于预订遍历,另一个用于按顺序遍历。

幸运的是 - 由于树是BST,因此有序遍历只是排序列表。

因此,您可以存储预订遍历(您可以尝试就地执行)并通过对重构中的元素进行排序,您可以进行有序遍历。

This post讨论了如何从顺序和预先遍历的树中重建树。

答案 1 :(得分:0)

要列出的二进制搜索树:

subTreeToList(node)
    if (node.hasLeft()) then subTreeToList(node.left, list)
    list.add(node.Value)
    if (node.hasRight()) subTreeToList(node.right, list)
    end if
subTreeToList end

treeToList(tree)
    subTreeToList(tree.root)
treeToList end

list <- new List()
treeToList(tree)

您需要将上述想法实现到您的解决方案中,如果您正在使用面向对象技术,那么列表和树应该是数据成员,否则它们应该作为引用传递给函数。

您可以构建树,知道树中的插入如下所示:

Insert(tree, value)
    if (tree.root is null) then
        tree.createRoot(value)
    else
        node <- tree.root
        while (((node.value < value) and (node.hasRight())) or ((node.value > value) and (node.hasLeft())))
            if ((node.value < value) and (node.hasRight())) then node <- node.right()
            else node <- node.left()
            end if
        while end
        if (node.value > value) then node.createLeft(value)
        else node.createRight(value)
        end if
    end if
insert end

您只需按顺序遍历列表并根据上面的伪代码调用实现的函数。祝你的作业好运。

答案 2 :(得分:0)

以下链接对您有所帮助,

Tree - to - List Conversion

答案 3 :(得分:0)

我想我自己找到了解决方案:下面是完整的Java实现 逻辑+伪代码如下 [1]找到树中最左边的节点,它将是LinkList的头部,将其存储在类中

Node HeadOfList = null;
    findTheHeadOfInorderList (Node root)
    {
        Node curr = root;

        while(curr.left != null)
            curr = curr.left;

        HeadOfList = curr; // Curr will hold the head of the list

    }

[2]反向遍历树,将其转换为右指针上的LL,并确保左指针始终指向节点的父节点。

updateInorderSuccessor(Node root, Node inorderNext, Node parent)
{
    if(root != null) 
                 //Recursively call with the right child
            updateInorderSuccessor(root.right, inorderNext, root);

                // Update the in-order successor in right pointer
        root.right = inorderNext; 
        inorderNext = root;

                //Recursively call with the left child
        updateInorderSuccessor(root.left, inorderNext, root);

                // Update the parent in left pointer
        root.left = parent;
    }
}

[3]将其转换回来:

遍历列表并找到左指针为null的节点, 将它作为根,打破链接列表中该根的链接以及其子节点......

现在链接列表分为两部分,一部分用于左子树,一部分用于右子树, 递归地找到这两个列表中的根并使它们成为左右子,请参考函数restoreBST()

Node restoreBST(Node head)
{
    if(head == null || (head.left == null && head.right == null)) return root;

    Node prev, root, right, curr;
            curr = head;

    // Traverse the list and find the node with left as null
    while(curr != null)
    {
        if(curr.left == null)
        {
            // Found the root of this tree
            root = curr;
                            // Save the head of the right list
            right = curr.right;
                            // Detach the children of the root just found, these will be updated later as a part of the recursive solution
            detachChildren(curr, head);
            break;
        }
        prev = curr;
        curr = curr.right;
    }

    // By now the root is found and the children of the root are detached from it.
    // Now disconnect the right pointer based connection in the list for the root node, so that list is broken in to two list, one for left subtree and one for right subtree
    prev.right = null;

    root.right = null;

    // Recursively call for left and right subtree

    root.left = restoreBST(head);
    root.right = restoreBST(right);

    //now root points to its proper children, lets return the root
    return root;
}

分离子项的逻辑很简单:遍历列表并查找左指针等于root的节点。

private void detachChildren(AvlNode root, AvlNode head) {
    AvlNode curr = head;

    while(curr != null)
    {
        if(curr.left == root)
        {
            curr.left = null;
        }
        curr = curr.right;
    }
}

答案 4 :(得分:0)

这是BST到LL的递归解决方案,希望您发现它很有用。

    Node BSTtoLL(BST root) {

        if(null == root) return null;

        Node l = BSTtoLL(root.left);
        Node r = BSTtoLL(root.right);

        Node l1 = null;
        if(null != l) {
            l1 = l;
            while(null != l.left) { l = l.left; }
            l.left = root;
            l.right = null;
        }
        if(null != r) {
            root.left = r;
            root.right = null;
        }

        if(null != l1) return l1;
        return root;
    }