如何使用给定的前序遍历给出的位序列创建递归二叉树?

时间:2017-11-28 11:51:45

标签: java algorithm binary-tree

我遇到麻烦的问题是这个。

  

每个节点由两位x1和x2表示。如果节点有左侧   child,x1为1.如果不是,则x1为0.类似于右边的情况   child,x2可以是1或0.通过这个规则,我们可以表示一个   由前序遍历形成的位序列下的二叉树。对于   例如,从" 11010011001000",我们可以构造以下树。   编写一个递归函数,可以采用给定的某个位序列   通过前序遍历并构造二叉树。

     

enter image description here

现在,我已经从类似问题Construct tree with pre-order traversal given获取信息,但它似乎有所不同,因为在这种情况下,您必须同时考虑单个节点的x1和x2 ......我&# 39;几个小时以来我一直在思考这个问题,但我不能用递归来提出一个好的逻辑。任何帮助,将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:2)

在达到50声望之前,我将这个声明放在我答案的第一行:

我想在评论中做一个简短的回复,但我没有足够的声誉,所以我正在做出完整的回答,希望我的错误答案仍然会有所帮助。

DFS非常适合这项任务 - 这基本上是预订遍历所做的:

def DFS(node):
    if(node == NULL) return
    sequence += notNull(node.l)
    sequence += notNull(node.r)
    DFS(node.l)
    DFS(node.r)

^^^这是你的序列的构建方式。

幸运的是,逆转是非常直接的:

def inverseDFS(node):
    if(node == NULL) return
    node.l = new Node() if(readBuffer(sequence) == '1') else NULL
    node.r = new Node() if(readBuffer(sequence) == '1') else NULL
    inverseDFS(node.l)
    inverseDFS(node.r)

^^^只修改第2行和第3行,现在不是根据子项的存在来确定序列的下一个字符,而是根据下一个字符读取来确定子项的存在,因为这是一个iff关系

这是一个更复杂的C ++代码,是的,我知道我的编码风格可能令其他人厌恶。

/* Author haleyk10198 */
/* FOR ACM-ICPC WF*/
#include <bits/stdc++.h>

using namespace std;

struct Node{
    static int nodeCnt;
    int id;
    Node *l, *r;
    Node(){
        l = r = nullptr;
        this->id = nodeCnt++;
    }
    friend ostream& operator<<(ostream&, const Node);
}*root = new Node();

ostream& operator<<(ostream &out, const Node node){
    cout << "Node id: " << node.id
          << " | left child is " << (node.l? node.l->id: -1)
          << " | right child is " << (node.r? node.r->id: -1) << endl;
}

int Node::nodeCnt, strStreamPos = 0;
string str;

void dfs(Node *node){
    if(not node)
        return;

    if(str[strStreamPos++] == '1')
        node->l = new Node();
    if(str[strStreamPos++] == '1')
        node->r = new Node();

    cout << *node << endl;

    dfs(node->l);
    dfs(node->r);   
}

int main(){

    cin >> str;

    dfs(root);

    return 0;
}

答案 1 :(得分:1)

解决方案可能只是在preorder中遍历您的树,同时从序列中读取(两个值并删除它们)并在必要时添加node

鉴于你有这个Node

class Node {
    int value;
    public Node left;
    public Node right;
}

您可以像这样创建一个树:

private static void createTree(Node root) {

    if(string.isEmpty() || root == null) {
        return;
    }

    if(string.charAt(0) == '1') {
        root.left = new Node();
    }

    if(string.charAt(1) == '1') {
        root.right = new Node();
    }
    string = string.substring(2);
    createTree(root.left);
    createTree(root.right);

}

其中string只是一个全局变量:static String string = "11010011001000";

你可以这样调用这个方法:

Node root = new Node();
createTree(root);

root将是树的实际根。