给定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]);
}
}
答案 0 :(得分:1)
您的代码可以使用,但是效率不高。 您没有使用数组的pre-order属性。实际上,您的代码是根据通用数组构建BST。 为了改进算法,您可以递归地构建树,并在每个节点中保留minRange和maxRange。如果下一个元素不在当前节点的范围内,请返回到父节点。
编辑: 您将得到同一棵树,但是如果原始树是平衡的,则复杂度将为O(N * logN),否则将为O(N ^ 2)。
我不想为您编写代码,但是我将尝试更好地解释我的算法: 保持指向您插入的最后一个节点的指针。同样,对于每个节点,保留子树的范围。 插入元素时,请从保留的指针开始。如果新节点在范围内,则将其作为子节点插入并更新指针。 如果不在该范围内,则将指针向上移动到其父级,然后尝试将其插入。 更新范围:如果将新节点作为左子节点插入,请将其maxRange设置为其父值。并分别为合适的孩子设置minRange。 在所有情况下,复杂度均为O(N)。