Algorithm 我们可以通过简单地将前序遍历中的元素按顺序插入到空树中,从前序遍历构造BST吗?

Algorithm 我们可以通过简单地将前序遍历中的元素按顺序插入到空树中,从前序遍历构造BST吗?,algorithm,binary-search-tree,Algorithm,Binary Search Tree,给定BST的前序遍历。我必须构造BST。 我可以简单地通过创建一个空的BST,然后从第一个元素开始并在最后一个元素结束,逐个插入预排序遍历中的元素,从预排序遍历构造BST吗 例如,考虑下面的BST:-< /P> 10 / \ 5 40 / \ \ 1 7 50 其前序遍历为: 105174050 通过创建一个空的BST,然后从第一个元素开始逐个插入前序遍历中的元素,我得到了精确的BST,解释如下: (empty tree) 插入前序

给定BST的前序遍历。我必须构造BST。 我可以简单地通过创建一个空的BST,然后从第一个元素开始并在最后一个元素结束,逐个插入预排序遍历中的元素,从预排序遍历构造BST吗

例如,考虑下面的BST:-< /P>

    10
   /   \
  5     40
 /  \      \
1    7      50
其前序遍历为:

105174050

通过创建一个空的BST,然后从第一个元素开始逐个插入前序遍历中的元素,我得到了精确的BST,解释如下:

(empty tree)
插入前序遍历的第一个元素:10

   10
插入前序遍历的第二个元素:5

   10
   /
  5
同样地


     10       
   / 
  5  
 /  
1   
在这里,我只需将前序遍历中的元素一个接一个地插入到一个空树中,就构建了精确的BST。 这个算法在所有情况下都有效吗?有没有这种算法不起作用的情况

void insertIntoTree(struct* Node,int val)
{
   if(Node == NULL)
   {
       Node = createNewNode(val);
       return;
   }
   if(val < Node->val)
      insertIntoTree(Node->left,val);
   else
      insertIntoTree(Node->right,val);

}
int main()
{
  int preorderlist[] = { 10,5,1,7,40,50};

  for(int i=0;i <= preorderlist.size();i++)
  {
     insertIntoTree(TreeRoot,preorderlist[i]);
  }

}
void insertIntoTree(结构*节点,int val)
{
if(Node==NULL)
{
Node=createNewNode(val);
返回;
}
if(valval)
插入树(节点->左侧,val);
其他的
插入树(节点->右侧,val);
}
int main()
{
int preorderlist[]={10,5,1,7,40,50};

对于(inti=0;i,您的代码可以工作,但效率不高。 您没有使用数组的pre-order属性。事实上,您的代码是从常规数组构建BST。 为了改进算法,可以递归地构建树,在每个节点中保留minRange和maxRange。如果下一个元素不在当前节点的范围内,请返回父节点

编辑: 您将得到相同的树,但是如果原始树是平衡的,那么复杂度将是O(N*logN),如果不是平衡的,那么复杂度将是O(N^2)

我不想为您编写代码,但我会尝试更好地解释我的算法: 保留指向插入的最后一个节点的指针。此外,对于每个节点,保留子树的范围。 插入元素时,请从保留的指针开始。如果新节点在范围内,请将其作为子节点插入并更新指针。 如果不在该范围内,请将指针向上移动到其父级,并尝试在那里插入。 要更新范围:如果将新节点作为左子节点插入,请将其maxRange设置为其父节点值。并分别为右子节点设置minRange。
所有情况的复杂性都是O(N)。

我不确定我是否理解这个问题。您所指的“所有情况”是什么?@RobertBaron“将任意BST转换为预排序形式,然后再转换回BST,是否总是会产生与原始BST相同的结果?”与大多数涉及BST的事情一样,答案涉及递归。您缺少子节点引用。仅创建新节点无法获得正确的BST。您需要返回节点并相应地插入父节点的左或右引用,因为当前作为不存在值的参数传递的左或右引用将是NULL。@RobertBaron是否存在上述算法无法工作的情况?从通用数组(也是BST的预序遍历)构建BST会给我原始BST(用于生成通用预序遍历数组的BST)吗。你能解释更多吗?维持每个节点的最小和最大范围是如何提高效率的?也许我忽略了一些东西。@shuki avraham。你的解决方案可以在O(n)中工作。但是我的解决方案也可以在O(nlogn)复杂度下工作吗?它将是O(nlogn)如果原始树是平衡的,我已经更新了我的答案来解释。完整的实现可以在@vivek_23中找到
     10
   /   \
  5     40
 /  \ 
1    7

     10
   /   \
  5     40
 /  \      \
1    7      50
void insertIntoTree(struct* Node,int val)
{
   if(Node == NULL)
   {
       Node = createNewNode(val);
       return;
   }
   if(val < Node->val)
      insertIntoTree(Node->left,val);
   else
      insertIntoTree(Node->right,val);

}
int main()
{
  int preorderlist[] = { 10,5,1,7,40,50};

  for(int i=0;i <= preorderlist.size();i++)
  {
     insertIntoTree(TreeRoot,preorderlist[i]);
  }

}