【问题标题】:How can I create a recursive binary tree with a bit sequence given by a given preorder traversal?如何创建具有给定前序遍历给出的位序列的递归二叉树?
【发布时间】:2017-11-28 11:51:45
【问题描述】:

我遇到的问题是这个。

每个节点由两个位 x1 和 x2 表示。如果节点有左 孩子,x1 是 1。如果不是,x1 是 0。对于权利的情况类似 孩子,x2 可以是 1 或 0。使用此规则,我们可以表示 由前序遍历形成的位序列下的二叉树。为了 例如,从“11010011001000”,我们可以构造如下树。 编写一个递归函数,它可以采用给定的某个位序列 通过前序遍历,构造二叉树。

现在,我从一个类似的问题Construct tree with pre-order traversal given 中获得了信息,但它似乎如此不同,因为在这种情况下,您必须同时考虑单个节点的 x1 和 x2...我一直在想这个几个小时,但我无法使用递归提出一个好的逻辑。任何帮助,将不胜感激。谢谢!

【问题讨论】:

  • “考虑单个节点的 x1 和 x2”是什么意思?所有的树都可以有可以有多个子节点的节点,否则它将是一个链表:) 那么这和你链接到的问题有什么区别?
  • 我的意思是在这个问题中,您还必须考虑将孩子(左侧或右侧)放在父母下方的位置,但在链接的问题中您不需要考虑这一点吗?

标签: java algorithm binary-tree


【解决方案1】:

在达到 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 行,现在不是通过 child 的存在来确定序列的下一个字符,而是可以根据读取的下一个字符来确定 child 的存在,因为这是一个 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;
}

【讨论】:

    【解决方案2】:

    一种解决方案可能是在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);
    
    }
    

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

    你可以这样调用方法:

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

    root 将是您树的实际根。

    【讨论】:

      【解决方案3】:

      您的问题看起来像这样: http://www.geeksforgeeks.org/construct-a-special-tree-from-given-preorder-traversal/

      我稍微修改了给定的代码以满足您案例的具体要求。我忽略了您问题中给定的节点(字母)顺序,只关注树的结构。正如预期的那样,时间复杂度为O(N)。一切似乎都很清楚,所以我没有提供更多信息。如果您有任何问题,请随时发表评论。

      public class BinaryTree {
          class Node {
              char data;
              Node left, right;
      
              Node(char item) {
                  data = item;
                  left = right = null;
              }
          }
      
          class Index {
              int index = 0;
          }
      
          Node root;
          Index i = new Index();
      
          Node constructTreeUtil(String bitSequence, Index index_ptr, int n, Node temp) {
              int index = index_ptr.index; 
      
              String bits = bitSequence.substring(index * 2, index * 2 + 2);
      
              if (index == n)
                  return null;
      
              temp = new Node((char) (index + 65));
              (index_ptr.index)++;
      
              if (bits.charAt(0) == '1')
                  temp.left = constructTreeUtil(bitSequence, index_ptr, n, temp.left);
      
              if (bits.charAt(1) == '1')
                  temp.right = constructTreeUtil(bitSequence, index_ptr, n, temp.right);
      
              return temp;
          }
      
          Node constructTree(String bitSequence, int n, Node node) {
              int index = 0;
              return constructTreeUtil(bitSequence, i, n, node);
          }
      
          public static void inorder(Node node) {
              if (node == null) return;
              System.out.println(node.data + "=> ");
      
              if (node.left != null)
                System.out.println("Left node: " + node.left.data);
      
              if (node.right != null)
                System.out.println("Right node: " + node.right.data);
      
              System.out.println();
              inorder(node.left);
              inorder(node.right);
          }
      
          public static void main(String args[]) {
              BinaryTree tree = new BinaryTree();
      
              // Bit sequence
              String bitSequence = "11010011001000";
      
              // Number of nodes
              int n = bitSequence.length() / 2;
      
              // Tree construction
              Node node = tree.constructTree(bitSequence, n, tree.root);
      
              // Print tree nodes inorder
              inorder(node);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-26
        • 2020-09-25
        • 1970-01-01
        • 2022-08-10
        • 2018-06-29
        • 1970-01-01
        • 2010-11-20
        • 2016-05-01
        相关资源
        最近更新 更多