二叉树中的线程二叉树实现

时间:2011-11-30 05:45:42

标签: java tree binary-tree

我正在为学校工作。它男子气概包含一个方法,该方法将二叉树作为输入并返回双线程树。例如(如果left child = null,那么left child将与之前的inorder parent连接,如果right child = null,它将链接到它的inorder succesor。现在我有了实现的想法......

我通过原始的BINARY树递归迭代并将inorder遍历存储到数组中。现在,因为我的教师实现要求线程树与二进制文件不同。我必须再次通过二叉树遍历并将每个节点从binaryNode转换为threadedNode,从而最终得到初始BinaryTree的“重复”但是作为Threadedtree类型。在我这样做之后,我再次遍历这个threadedTree,每当我看到一个空的左或右子时,我就会引用inorder arraylist并找到线程。

现在您可能已经注意到这是非常低效的,我基本上是遍历树3次。我的教授已经表示,这可以通过一次遍历递归完成,实质上转换为threadedNode并一次查找所有线程。我尝试了多种方法,但我找不到一种有效的方法。有没有人有任何提示或某种方式我可以实现它?感谢

这是教师

指定的方法
public static <T> ThreadedNode<T> thread(BinaryNode<T> root)
{
   //threads a binary tree
}

2 个答案:

答案 0 :(得分:2)

教练是对的。一次遍历就足够了。

遍历原始二叉树,在您走过这棵树时创建新的ThreadedNode

public static <T> ThreadedNode<T> thread(BinaryNode<T> root) {
    // We'll be keeping track of the "previous" node as we go, so use
    // a recursive helper method.  At first, there is no previous.
    return threadHelper(root, null);
}

private static <T> ThreadedNode<T> threadHelper(BinaryNode<T> n, ThreadedNode<T> previous) {

    // Create a new threaded node from the current root.  Note that the threaded nodes
    // are actually created in "preorder".  Assume the ThreadedNode constructor sets
    // the left, right, threadLeft, and threadRight fields to null.
    ThreadedNode<T> t = new ThreadedNode<T>(n.getData());

    // First go down the left side, if necessary.
    if (n.getLeft() != null) {
        // If there is a left child we have to descend.  Note that as we go down the
        // left side the previous doesn't change, until we start "backing up".
        t.left = threadHelper(n.getLeft(), previous);
        previous = t.left;
    } else {
        // If there is no left child, connect our left thread to the previous.
        t.threadLeft = previous;
    }

    // Now before we go down the right side, see if the previous
    // node (it will be in the left subtree) needs to point here.
    if (previous != null && previous.right == null) {
        previous.threadRight = t;
    }

    if (n.getRight() != null) {
        // If there is a right child we can descend the right.  As we go down we
        // update previous to the current node.  We do this just by passing the current
        // node as the second parameter.
        t.right = threadHelper(n.getRight(), t);
    } else {
        // No right child, no worries.  We'll hook up our thread-right pointer
        // later.
    }
    return t;
}

考虑树(A(B(D)())C)。您在inorder遍历中遇到的第一个节点是D.没有上一个节点。所以像以前一样保存D.然后你击中的下一个节点是B.前一个节点是D,它没有正确的子节点,所以从D到B添加一个带螺纹的右指针。然后在B之前设置并继续。接下来你点击A. B没有正确的孩子,所以添加一个从B到A的线程右链接.A有一个正确的孩子,所以继续,设置在A之前。下一个节点是C. C没有左子,所以添加一个从C到前面的当前值的螺纹左连接,即A。

答案 1 :(得分:0)

您可以跳过在方法中提到的第二次遍历。您可以动态地将节点从BinaryNode转换为ThreadedNode。我认为,对于inorder遍历,以及查找线程并将其转换为aThreadedTree,您仍需要遍历两次。

对于即时转换,您可以使用教师提供的方法。

HTH!