在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