Tree 将预先排序的节点列表转换回二叉树

Tree 将预先排序的节点列表转换回二叉树,tree,language-agnostic,binary-tree,preorder,Tree,Language Agnostic,Binary Tree,Preorder,我有一个预先排序的节点列表,我需要将其转换回树。我对生成的树有一些保证 这意味着每个节点将有0或2个子节点 无论节点是叶节点还是分支节点都包含在预排序列表中 我确信,只要上述两个约束保持不变,就可以创建一棵树 预排序中节点列表的一个示例可能是: Branch(1), Branch(2), Leaf(3), Branch(4), Leaf(5), Leaf(6), Branch(7) 生成的树: 1 / \ 2 7 / \ 3 4

我有一个预先排序的节点列表,我需要将其转换回树。我对生成的树有一些保证

  • 这意味着每个节点将有0或2个子节点
  • 无论节点是叶节点还是分支节点都包含在预排序列表中
我确信,只要上述两个约束保持不变,就可以创建一棵树

预排序中节点列表的一个示例可能是:

Branch(1), Branch(2), Leaf(3), Branch(4), Leaf(5), Leaf(6), Branch(7)
生成的树:

       1
     /   \
   2       7
  / \
 3   4
    / \
   5   6
我想不出还有其他树可以从上面的预订单列表中构建

我尝试过几种不同的方法(主要是使用堆栈和队列),但我在这上面花了几个小时,没有任何方法可以起作用


<>我希望在C中,C ++,python,java,或者甚至伪代码中的生锈,但是C++中的提示或解决方案会被理解。

你可以使用预排序遍历来恢复二叉树,当且仅当树是二叉搜索树时。简单地说,按照与遍历相同的顺序插入节点

但是如果您的树不是二叉搜索树,那么您需要在遍历中放置外部节点(空指针)。有些人喜欢这样:

void preorder(Node * root)
{
  if (root == Node::NullPtr)
    {
      cout << "NULL ";
      return;
    }

  cout << root->key << " ";
  preorder(root->left);
  preorder(root->right);
}
void预订单(节点*根)
{
if(root==Node::NullPtr)
{
不正确);
}
假设您在
向量
对象中进行了前序遍历,那么为了获得原始树,您可以执行以下操作:

Node * restore(const vector<string> & a, int & i)
{
  string key = a[i++];
  if (key == "NULL")
    return Node::NullPtr;

  Node * p = new Node;
  p->key = key;
  p->left = preorder(a, i);
  p->right = preorder(a, i);

  return p;
}
Node*还原(常量向量&a、int&i)
{
字符串键=a[i++];
如果(键==“空”)
返回节点::NullPtr;
Node*p=新节点;
p->key=key;
p->左=预订单(a,i);
p->right=预订单(a,i);
返回p;
}
官方界面将是:

Node * restore(const vector<string> & a)
{
  int i = 0;
  return restore(a, i)
}
节点*还原(常量向量&a)
{
int i=0;
返回还原(a,i)
}

在给它一些时间之后,我已经为我的问题创建了一个解决方案

基本上,您有一个变量来保存您正在处理的当前节点,从根开始。当遇到分支时,您将分支添加到当前节点的子节点,然后将当前节点设置为该分支。当遇到叶时,您将叶添加到当前节点的子节点。您可以在while循环中执行此操作,直到列表结束为空。在每次循环迭代开始时,检查当前节点的子节点是否==2,如果是,则将节点指向其父节点,并继续这样做,直到当前节点变量指向具有<2个子节点的节点

下面是我的带条除锈实现:

struct Node { /* ... */ }
impl Node { /* ... */ }

enum NodeType {
    Branch(i32),
    Leaf(i32),
}

impl NodeType { /* ... */ }

fn list_to_tree(list: &[NodeType]) -> Node {
    let mut iter = list.iter();
    let root = Node::new(iter.next().unwrap().get_data());
    let mut node = &root;

    while let Some(next) = iter.next() {
        while node.child_count() == 2 {
            node = node.parent_ref();
        }

        match next {
            NodeType::Branch(data) => {
                node.add_child(Node::new(data));
                node = next;
            }
            NodeType::Leaf(data) => {
                node.add_child(Node::new(data));
            }
        }
    }

    root
}

它假定给定了一个非空列表,并且该列表是一个正确的预排序列表,该列表由一棵树组成,每个节点正好有0或2个子节点。

它不是bst,因此第一个解决方案将不起作用。您也不需要在预排序列表中存储空指针,因为可以保证每个节点都有0或2个子节点,并且她的节点是叶或分支包含在预序列表的每个元素中。@ NICKEB96我真的很感激知道。例如,考虑2个节点。具有根2和左子1的树与根1和右子2的树具有相同的前序遍历。如何区分它们?更多不同的树具有相同的前序遍历。@nickeb96你是对的。我没有理解你的问题陈述。抱歉