Data structures 从按序和按级遍历构造二叉树
首先,我想声明这不是家庭作业。我正在准备面试,遇到了这个问题。我想我们可以通过和遍历的定义。:- 例如:Data structures 从按序和按级遍历构造二叉树,data-structures,binary-tree,inorder,Data Structures,Binary Tree,Inorder,首先,我想声明这不是家庭作业。我正在准备面试,遇到了这个问题。我想我们可以通过和遍历的定义。:- 例如: 50 / \ 10 60 / \ / \ 5 20 55 70 / / \ 51 65 80 上述树的顺序和级别顺序遍历为: 5,10,20,50,51,55,60,65,70,80 50,10,60,5,20,55,70,51,65,80 我的想法是: (1)
50
/ \
10 60
/ \ / \
5 20 55 70
/ / \
51 65 80
上述树的顺序和级别顺序遍历为:
5,10,20,50,51,55,60,65,70,80
50,10,60,5,20,55,70,51,65,80
我的想法是:
(1) 遍历levelorder数组以找出第一个元素
它出现在顺序数组中。我们称这个元素为current
根
(2) 在顺序数组中查找当前根的索引。秩序井然
数组由索引分隔。顺序数组的左侧
是当前根目录的左子树和
顺序数组是当前根的右子树
(3) 将顺序数组更新为其左侧,然后转至步骤1
(4) 将顺序数组更新为其右侧,然后转至步骤2
以上面的树为例
有人能帮我验证我的解决方案吗?
如果再给你一个,你会非常感激。事实上,这个想法很简单,你只需要确保遍历序列正确与否。例如,你想按顺序遍历,你可以简单地这样想:从左到右,从下到上
按照杠杆顺序,你可以从上到下,从左到右,一步一步地移动。我想你走对了。下面是我使用您的数据编制的工作代码
/*
//construct a bst using inorder & levelorder traversals.
//inorder - 5, 10, 20, 50, 51, 55, 60, 65, 70, 80
//levelorder - 50, 10, 60, 5, 20, 55, 70, 51, 65, 80
50
/ \
10 60
/ \ / \
5 20 55 70
/ / \
51 65 80
*/
struct node *construct_bst3(int inorder[], int levelorder[], int in_start, int in_end)
{
static int levelindex = 0;
struct node *nnode = create_node(levelorder[levelindex++]);
if (in_start == in_end)
return nnode;
//else find the index of this node in inorder array. left of it is left subtree, right of this index is right.
int in_index = search_arr(inorder, in_start, in_end, nnode->data);
//using in_index from inorder array, constructing left & right subtrees.
nnode->left = construct_bst3(inorder, levelorder, in_start, in_index-1);
nnode->right = construct_bst3(inorder, levelorder, in_index+1, in_end);
return nnode;
}
静态树maketreefrominorder和levelorder(int[]inorder,int[]lorder,int s,int n,int cnt1){
如果(s>n | | s>=inorder.length | | n>=inorder.length | | cnt1>=inorder.length){
返回null;
}
int mIndex=搜索(领主[cnt1],顺序,s,n);
树t=新树(主[cnt1]);
cnt1=2*cnt1+1;
t、 左=maketreefrominorder和levelorder(inorder、lorder、s、mIndex-1、cnt1);
//边界情况
如果(cnt1
元素的分离将需要使用哈希表的O(n),因此在平衡树中的总体复杂性将是O(nlogn),但它将变成O(n^2)当树不平衡时。我认为这不符合顺序。我只是编写了一个程序来验证它。顺序遍历似乎没有问题。您能为示例树提供顺序遍历,让我再次检查一下吗?似乎我错了。这看起来是正确的,抱歉。您好,欢迎来到stackoverflow!但是,我知道我不明白这是怎么回答这个问题的。海报问是否有人可以验证他的算法的正确性,而不是一个实现。如果你认为你的实现以某种方式提供了这种验证,请在你的答案中解释。另外,请确保你的答案格式正确,可读性好。什么是时空比较这个算法的存在性?O(n)?@AnV它不可能是O(n)。它可能是O(logn)的某个因子。我们需要为数组中的所有n个元素创建节点,然后在返回时将它们附加到它们的父元素。所以我认为TC应该是O(n)。你能解释一下它是如何成为O(logn)的因子的吗?@AnV抱歉!不知道我写上述评论时在想什么。上述方法的时间复杂度上限为O(n3)。我们在搜索中进行线性扫描,然后进行左、右子树。如果我们在搜索中使用查找表,我们可以得到O(n2)
/*
//construct a bst using inorder & levelorder traversals.
//inorder - 5, 10, 20, 50, 51, 55, 60, 65, 70, 80
//levelorder - 50, 10, 60, 5, 20, 55, 70, 51, 65, 80
50
/ \
10 60
/ \ / \
5 20 55 70
/ / \
51 65 80
*/
struct node *construct_bst3(int inorder[], int levelorder[], int in_start, int in_end)
{
static int levelindex = 0;
struct node *nnode = create_node(levelorder[levelindex++]);
if (in_start == in_end)
return nnode;
//else find the index of this node in inorder array. left of it is left subtree, right of this index is right.
int in_index = search_arr(inorder, in_start, in_end, nnode->data);
//using in_index from inorder array, constructing left & right subtrees.
nnode->left = construct_bst3(inorder, levelorder, in_start, in_index-1);
nnode->right = construct_bst3(inorder, levelorder, in_index+1, in_end);
return nnode;
}
static tree MakeTreeFromInorderAndLevelOrder(int[] inorder,int[] lorder,int s,int n,int cnt1) {
if(s>n || s>=inorder.length || n>=inorder.length || cnt1>=inorder.length) {
return null;
}
int mIndex = Search(lorder[cnt1],inorder,s,n);
tree t = new tree(lorder[cnt1]);
cnt1 = 2*cnt1 + 1;
t.left = MakeTreeFromInorderAndLevelOrder(inorder,lorder,s,mIndex-1,cnt1);
//Boundary case
if(cnt1<inorder.length && t.left==null) {
t.right = MakeTreeFromInorderAndLevelOrder(inorder,lorder,mIndex+1,n,cnt1);
}
else {
cnt1 -=1;
cnt1 /=2;
cnt1 = 2*cnt1 + 2;
t.right = MakeTreeFromInorderAndLevelOrder(inorder,lorder,mIndex+1,n,cnt1);
//Boundary case
if(t.right ==null && cnt1<inorder.length) {
t.left = MakeTreeFromInorderAndLevelOrder(inorder,lorder,s,mIndex-1,cnt1);
}
}
return t;
}
node *construct (in, s, e, level)
{
while (level order has element)
{
make the root by taking the first element from level order
find the index of root->Val in in order.
segregate the elements of left subtree and right subtree (make sure while
segregating from level order the order of element should be same) call them
leftLevel[] and rightLevel[]
construct tree by recursively calling
root->left = construct(inorder,s, index-1, leftLevel);
root->right = construct(inorder, index+1, e, rightlevel);
return root;
}
}