我们可以利用数学归纳法证明:对排好序的数组,采用“二分查找”思想(总是取中间元素作为根节点,然后递归构造左右子树)构造出的二叉树一定是完全二叉树。
证明:
n=0时 得到空树,空树满足完全二叉树的定义;
n=1时 得到只有一个节点的树,该树显然是完全二叉树。
假设对于任意小于 n 的正整数 k,用该方法构造出的包含 k 个元素的二叉树都是完全二叉树。
考虑一个包含 n 个元素的排好序数组。
构造根节点:取数组中间元素作为根节点;
划分左右子数组:剩下的 n−1 个元素被分为两部分,左子数组的节点个数为 ⌊ 2n−1 ⌋;右子数组的节点个数为 ⌈ 2n−1 ⌉。
注意到两部分的节点数之差不超过 1,而且通常左侧节点数不少于右侧。
递归构造子树,根据归纳假设:左子数组构造出的左子树是完全二叉树;右子数组构造出的右子树也是完全二叉树。
由于左右子树的节点数之差最多为 1,且左子树节点数不少,整个树的各层(除了最后一层)均能被填满。
最后一层的节点来自左右子树,由于构造过程中总是先填充左侧,再填充右侧,所以最后一层的节点一定是连续地排列在左侧。
因此,整体构造出的树满足完全二叉树的定义。
折半查找(又叫二分查找)时间复杂度推导:
基本思想: 每次将搜索范围缩小一半,直到找到目标或范围为空。
设时间复杂度为 ( T(n) ),每次操作后问题规模减半,且每次比较操作的时间为常数 ( O(1) )。因此,递推关系为:
T ( n ) = T ( n 2 ) + O ( 1 ) T(n) = T\left(\frac{n}{2}\right) + O(1) T(n)=T(2n)+O(1)
递推关系可以展开为:
T ( n ) = T ( n 2 ) + C T(n) = T\left(\frac{n}{2}\right) + C T(n)=T(2n)+C
T ( n ) = T ( n 4 ) + 2 C T(n) = T\left(\frac{n}{4}\right) + 2C T(n)=T(4n)+2C
⋮ \vdots ⋮
T ( n ) = T ( 1 ) + C ⋅ log 2 n T(n) = T(1) + C \cdot \log_2 n T(n)=T(1)+C⋅log2n
其中, C C C 为常数,递归深度 k k k 满足 n 2 k = 1 \frac{n}{2^k} = 1 2kn=1,解得 k = log 2 n k = \log_2 n k=log2n。
递归式符合主定理,解得时间复杂度为:
T ( n ) = O ( log 2 n ) T(n) = O(\log_2 n) T(n)=O(log2n)
最坏情况下,二分查找需要 ⌊ log 2 n ⌋ + 1 \lfloor \log_2 n \rfloor + 1 ⌊log2n⌋+1 次循环操作。由于常数项可以忽略不计,因此总时间复杂度为:
O ( log n ) O(\log n) O(logn)