在Java中从扁平列表重建二叉搜索树?
我有这段代码,用于从预排序遍历元素的扁平列表重建二叉搜索树 我看到这段代码在工作,但无法理解它是如何工作的。代码如下:在Java中从扁平列表重建二叉搜索树?,java,binary-tree,binary-search-tree,preorder,Java,Binary Tree,Binary Search Tree,Preorder,我有这段代码,用于从预排序遍历元素的扁平列表重建二叉搜索树 我看到这段代码在工作,但无法理解它是如何工作的。代码如下: public static Node reconstructfromflattenBST(List<Integer> list){ if (list.isEmpty()){ return null; } int data = list.remove(0); Node root =
public static Node reconstructfromflattenBST(List<Integer> list){
if (list.isEmpty()){
return null;
}
int data = list.remove(0);
Node root = new Node(data);
root.left=reconstructfromflattenBST(list);
root.right=reconstructfromflattenBST(list);
return root;
}
你说得对。如果在展平树时,也写入了空节点(可能为空整数),则:
Integer data = list.remove(0);
if (data == null) {
return null;
}
Node root = new Node(data.intValue());
将重建完全相同的树。
也就是说:展平添加停止的空叶
List<Integer> list = new LinkedList<>();
flatten(list, tree);
void flatten(List<Integer> list, Node tree) {
if (tree == null) {
list.add(null);
return;
}
list.add(tree.data);
flatten(tree.left);
flatten(tree.right);
}
List List=newlinkedlist();
展平(列表、树);
空心展开(列表、节点树){
if(tree==null){
list.add(空);
返回;
}
列表.添加(树.数据);
展平(树左);
展平(树,右);
}
或使用有序树:
public static Node reconstructfromflattenBST(List<Integer> list){
reconstruct(list, Integer.MAX_VALUE, true);
}
public static Node reconstruct(List<Integer> list, int priorData, boolean left){
if (list.isEmpty()){
return null;
}
int data = list.remove(0);
if ((data <= priorData) != left) {
return null;
}
Node root = new Node(data);
root.left=reconstruct(list, data, true);
root.right=reconstruct(list, data, false);
return root;
}
publicstaticnode从blattbst(列表)重建{
重构(列表,Integer.MAX_值,true);
}
公共静态节点重构(列表,int-priorData,布尔左){
if(list.isEmpty()){
返回null;
}
int data=list.remove(0);
如果((数据)
根据我对该方法的理解,不会创建右树。因为当控件到达根目录时,右
,列表
为空
对
但这种方法显然有效
我给出了一个[5 3 1 4 8 6 9]的预顺序输入。在构建了树之后,我对构建的树进行了预顺序遍历,它给出了与输入列表相同的元素顺序
这一观察并不反驳正确的子树总是空的
更好的单元测试将构造一棵树,将其展平,重建,并比较重建的树是否与原始树具有相同的形状。这样的测试将失败。事实上,不可能从节点的预排序列表忠实地重建树,因为不同的树具有相同的预排序列表。例如,两者
1 1
\ / \
2 2 3
\
3
拥有预排序列表1 2 3。我认为问题在于写出树的预排序值并不能保证树最初是BST,因此初始函数的输出应该是一根从左侧向下的棍子,以5为根
5
3
1
4
8
6
9
此树的前序遍历为[5,3,1,4,8,6,9],但它不是BST,因此不是树的正确表示形式。Joop Eggen显示的版本正确我认为右子树从来没有被构造过,因为列表在到达根目录的那行代码之前就被清空了。右`被分配了,正如你可以在我的代码上面看到的,我没有做data==null
检查,这是如何工作的?我已经包含了我的展平子例程,它可以工作。你可以得到一个带有nod的树是的,只有左分支被填充。没错..但当我进行预排序遍历时,它会正确地打印输入列表,这是怎么回事?左边的那个不是BST。这里的想法是将树结构持久化到数组中并重建回同一棵树。预排序数组是最好的,因为可以从它而不是从任何东西重建BSTng else..对,如果数字不同,则BST由其前序列表标识,但您重建的树不是BST。我想您是对的。上述重新构造不会返回有效的BST。
5
3
1
4
8
6
9