仅提供后序遍历的二叉树有序遍历

时间:2019-03-03 09:31:24

标签: algorithm binary-tree

我在编码挑战中遇到一个问题。

完整的二叉树是一棵二叉树,其中除叶节点之外的每个节点都有两个子节点,并且边缘高度为h的树的最后一级有2^h个叶节点。 / p>

您的任务很简单,给定遍历post-order遍历完整的二叉树,请打印其in-order遍历。

二叉树中的元素属于字符类型,即每个节点存储一个字符值。


输入/输出格式

输入格式:

只有一个字符串输入表示后遍历。

约束:

1 <= input.length <= 1000

输出格式:

输出一个字符串,表示二叉树的有序遍历


样品

样本输入0:

  

BCA

样本输出0:

  

BAC

2 个答案:

答案 0 :(得分:1)

您可以动态地进行递归操作。


机制

  • 将树分成三部分:leftrightroot
  • 按以下顺序重新加入他们:leftrootright
  • 递归拆分,直到子树的长度为1。

代码-在Java

PostToInOrder.java

public class PostToInOrder {
    public static String convert(String post) {
        checkPerfect(post); // check whether tree is perfect,

        return convertInner(post);
    }

    private static String convertInner(String post) {
        int len = post.length();
        if (len == 1) return post; // base case,

        String left = post.substring(0, len >> 1); // left of post,
        String right = post.substring(len >> 1, len - 1); // right of post,
        char root = post.charAt(len - 1); // root of post,

        return convertInner(left) + root + convertInner(right);
    }

    private static void checkPerfect(String tree) {
        if (!isPerfect(tree)) throw new IllegalArgumentException("input is not perfect tree, size: " + tree.length());
    }

    private static boolean isPerfect(String tree) {
        int len = tree.length();
        if (len < 1) return false;

        while (len != 0) {
            if ((len & 1) == 0) return false;
            len >>= 1;
        }

        return true;
    }
}

PostToInOrderTest.java:
(单元测试,通过TestNG

import org.testng.Assert;
import org.testng.annotations.Test;

public class PostToInOrderTest {
    @Test
    public void test() {
        Assert.assertEquals(PostToInOrder.convert("BCA"), "BAC");
        Assert.assertEquals(PostToInOrder.convert("02146538A9CEDB7"), "0123456789ABCDE");

        Assert.assertEquals(PostToInOrder.convert("A"), "A"); // single element,
    }

    @Test(expectedExceptions = IllegalArgumentException.class)
    public void test_invalid_empty() {
        PostToInOrder.convert("");
    }

    @Test(expectedExceptions = IllegalArgumentException.class)
    public void test_invalid_notPerfect() {
        PostToInOrder.convert("AB");
    }
}

顺便说一句:

  • 所描述的树是perfect binary tree
    这是完整二叉树的子类型。
    完整的树不一定是完美的,它的最后一级可能缺少一些叶子。
    例如AB是一棵完整的树,但不是完美的树。

答案 1 :(得分:1)

我确实准备好了完整的答案,但是@EricWang击败了我以实现该目标。因此,这是一个补充性答案,详细描述了该过程。请接受他的回答。


我将使用后遍历DEBFGCA,因为考虑更多的节点很有用。

因为树是完整的,所以对于任何给定的节点,我们知道左侧的子代数与右侧的子代数相同。因此,我们可以查看后遍历DEBFGCA并知道它具有结构LLLRRRN,其中L是左子树R的后遍历是右子树的后序遍历,N是节点本身。

更一般地说,我们知道左子树的后序遍历是字符0(tree.length - 1)/2 - 1,右子树的后序遍历是字符(tree.length -1)/2 - 1tree.length - 2。该节点是最后一个字符,位于tree.length - 1

很显然,要将其更改为有序遍历,我们只需标识左右子树,将它们更改为有序遍历,然后返回LLLNRRR。我们可以使用递归将左和右子树按顺序转换。

例如,从DEBFGCA开始。我们知道结构为LLLRRRN,所以左子树为DEB,右子树为FGC,节点为A。我们想将DEB变成有序...

过程DEB。我们知道左子树是D,右子树是E,节点是B。两个子树的长度均为1,叶子也是如此。无需进一步递归。返回LNR,即DBE

过程FGC。和以前一样,返回FCG

现在我们知道左侧的顺序是DBE,右侧的顺序是FCG。返回LLLNRRR,即DBEAFCG