使用预订

时间:2016-05-11 16:29:38

标签: time-complexity binary-search-tree master-theorem

我尝试编写程序,使用预订序列构建二叉搜索树。我知道有很多解决方案:最小/最大算法,经典(或“明显的”递归)或甚至迭代而不是递归。

我试图实现经典递归:预先遍历遍历的第一个元素是根。然后我搜索所有小于根的元素。所有这些元素都将成为左子树的一部分,其他值将成为右子树的一部分。我重复一遍,直到我构建所有的子句。这是一种非常经典的方法。

这是我的代码:

public static TreeNode constructInOrderTree(int[] inorder) { 
    return constructInOrderTree(inorder, 0, inorder.length-1);
}

 private static TreeNode constructInOrderTree(int[] inorder, int start, int end){
 if(start>end){
        return null;
 }

int rootValue = inorder[start];
TreeNode root = new TreeNode(rootValue);

int k = 0; 
for (int i =0; i< inorder.length; i++){
    if (inorder[i]<= rootValue){ 
        k=i;
    }
}

 root.left = constructInOrderTree(inorder, start+1, k);
 root.right= constructInOrderTree(inorder, k+1, end);

    return root;
   }

我的问题是:此算法的时间复杂度是多少?是O(n ^ 2)还是O(n * log(n))?

我在stackoverflow中搜索了这里,但我发现了许多相互矛盾的答案。有时,有人说它是O(n ^ 2),有时O(n * log(n)),我真的很困惑。

我们可以在这里应用主定理吗?如果是,“也许”我们可以考虑每次我们将树分成两个子树(相等的部分),所以我们将得到关系:(O(n)是在数组中搜索的复杂性)

T(n)= 1/2 * T(n / 2)+ O(n)

这会给我们带来O(n*log(n))的复杂性。但是,我认为这不是真的,我们将树分成相等的部分,因为我们在数组中搜索,直到我们找到了足够的元素没有?

可以在这里应用主定理吗?

1 个答案:

答案 0 :(得分:1)

<强> Forethoughts:

不,WC中既不是O(n^2)也不是O(nlogn)。由于树木的性质以及您不对每个元素执行任何复杂操作的事实。所有你做的就是输出它,而不是用一些比较算法对它进行排序。

然后WC将是O(n)

这就是当树被歪斜时,即根的子树中的一个是空的。然后你有一个简单的链表。然后输出它,您必须至少访问每个元素一次,给出O(n)

<强>证明:

让我们假设正确的子树是空的,每次调用的努力是不变的(只打印出来)。然后

T(n) = T(n-1) + T(0) + c
T(n) = T(n-2) + 2T(0) + 2c
.
.
T(n) = nT(0) + nc = n(T(0) + c)

由于T(0)c是常量,因此您最终会加入O(n)