【问题标题】:Can we construct a BST from a pre-order traversal simply by inserting the elements in preorder traversal in sequence into an empty tree?我们可以简单地通过将前序遍历中的元素按顺序插入一棵空树来从前序遍历构造一个 BST 吗?
【发布时间】:2019-10-23 17:02:34
【问题描述】:

给定一个 BST 的前序遍历。我必须构造 BST。 我可以简单地通过创建一个空的BST,然后从第一个元素开始到最后一个元素将元素一个一个地插入到空BST中来从前序遍历构造BST吗?

例如,考虑以下 BST:-

    10
   /   \
  5     40
 /  \      \
1    7      50

它的前序遍历是:

10 5 1 7 40 50

通过创建一个空的 BST,然后从第一个元素开始在前序遍历中一个接一个地插入元素,可以得到确切的 BST,解释如下:

(empty tree)

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

   10

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

   10
   /
  5

同样,


     10       
   / 
  5  
 /  
1   
     10
   /   
  5    
 /  \  
1    7 
     10
   /   \
  5     40
 /  \ 
1    7

     10
   /   \
  5     40
 /  \      \
1    7      50

在这里,我只是通过将前序遍历中的元素一个接一个地插入到一棵空树中来构造了确切的 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]);
  }

}

【问题讨论】:

  • 不确定我是否理解这个问题。您所指的“所有案例”是什么?
  • @RobertBaron “将任意 BST 转换为预购形式,然后再转换回 BST,是否总是会产生与原始 BST 相同的结果?”与涉及 BST 的大多数事情一样,答案涉及递归。
  • 您缺少子节点引用。仅创建一个新节点不会为您提供正确的 BST。您需要返回节点并相应地插入父级的左或右引用,因为当前作为不存在值的参数传递的左或右引用将为 NULL。
  • @RobertBaron 有没有上述算法行不通的情况?

标签: algorithm binary-search-tree


【解决方案1】:

您的代码可以工作,但效率不高。 您没有使用数组的预购属性。事实上,您的代码正在从一个通用数组构建一个 BST。 为了改进您的算法,您可以递归地构建树,在每个节点中保留 minRange 和 maxRange。如果下一个元素超出当前节点的范围,则返回父节点。

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

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

【讨论】:

  • 你能解释更多吗?保持每个节点的最小和最大范围如何提高效率?也许我忽略了一些东西。
  • @shuki avraham。你的解决方案可以在 O(n) 中工作。但是我的解决方案也可以在 O(nlogn) 复杂度下工作吗?
  • 如果原始树是平衡的,它将是 O(NlogN),我已经更新了我的答案来解释。
  • 完整实现见geeksforgeeks.org/?p=25203@vivek_23
猜你喜欢
  • 2018-11-06
  • 1970-01-01
  • 2022-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-03
  • 1970-01-01
  • 2021-01-14
相关资源
最近更新 更多