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你是对的。我没有理解你的问题陈述。抱歉