在最坏的情况下,从已知列表创建二叉树将是O(n 2 ),但是平均情况是O(n log n)。最坏情况和平均情况之间的差异取决于树在创建后的不平衡程度。如果是maxDepth == n
,那么这是最糟糕的情况,如果maxDepth == log(n)
那么这是最好的情况。在构建树之前了解maxDepth
可以很好地了解创建树的运行时间。
最大深度
有没有办法在O(n)时间内确定最大深度(或近似值)?我想不出办法做到这一点。相反,我选择尝试找到初始列表的“已排序”。
排序岬
在二叉树的最坏情况示例中,排序列表最终在功能上等同于链表。列表排序越多,二叉树的性能越差。我找不到任何可以给出列表的“排序因子”的东西。我尝试过的算法可以满足我的需求,但感觉并不“正确”*。
public double sortFactor(int[] ar) {
//assume lists are larger than 10000 elements
int prevSum = ar[0] + ar[1] + ar[2];
int numIncreasing = 0;
for(int i=3; i < ar.length-3; i+=3) {
int sum = ar[i] + ar[i+1] + ar[2];
if (sum > prevSum) {
numIncreasing++;
}
prevSum = sum;
}
int totalSets = ar.length/3;
double sortFactor = (double) numIncreasing / (double) totalSets;
return sortFactor;
}
*“right” - 此算法不基于任何基于实地的证据或概念。它基于模糊数据,以查看3个组是否按排序到半排序。选择3是因为它大于1和2。
问题
有没有办法在O(n)时间内根据给定列表确定未来二叉树的最大深度(或近似值)?
“sorted-ness”是列表的可确定属性吗?可以在O(n)时间内确定还是需要更大的时间复杂度空间?
声明
我知道自平衡二叉树(Red-Black,AVL),但出于这个问题的目的,它们是无趣的。它们与上述任何一个问题都没有关系,而是解决了这两个问题起源的背景信息。
答案 0 :(得分:1)
当然可以在时间O(n log n)内完成。我对线性决策树模型中的O(n)持怀疑态度,但我没有任何证据。
保持从现有键之间的间隔到新节点插入深度的有序映射。对于每个点的顺序,找到它的间隔并在深度加1处分成两个。
3, 1, 4, 5, 9
上执行的示例:
(-inf, inf): 0
insert 3
(-inf, 3): 1
(3, inf): 1
insert 1
(-inf, 1): 2
(1, 3): 2
(3, inf): 1
insert 4
(-inf, 1): 2
(1, 3): 2
(3, 4): 2
(4, inf): 2
insert 5
(-inf, 1): 2
(1, 3): 2
(3, 4): 2
(4, 5): 3
(5, inf): 3
insert 9
(-inf, 1): 2
(1, 3): 2
(3, 4): 2
(4, 5): 3
(5, 9): 4
(9, inf): 4
获得深度4
的答案(包括空节点)。这是树(*
表示null):
3
/ \
/ \
/ \
1 4
/ \ / \
* * * 5
/ \
* 9
/ \
* *