算法题(选自2020年清华912真题)
- A,B,C,D和F都是3分每题,E为5分。下图给出二叉树的结构体声明:
struct BinNode {
//二叉树节点
BinNodePosi(T) lc;
BinNodePosi(T) rc;
int size;
}
A. 完全二叉树左子树的规模为__,请给出递推公式;
B. 给出A的伪代码实现;
C. 找出中序遍历序列第k个节点;
D. 对某一节点通过zigzag操作成为其祖先a的孩子;
E. 给出将一棵树转化为完全二叉树的算法,要求时间复杂度为O(nlogn),迭代深度不超过O(logn);
F. 证明你在E中给出的算法满足复杂度和迭代深度的要求。
参考答案:
A. 对于高度为h的满二叉树,其规模size = 2^(h+1) - 1; 对于节点数为n的完全二叉树,其高度h = floor(logn)。(无特殊说明时,log函数的底数默认为2;floor函数取下整,例如:log16=4,floor(1.5)=1。)
对于一棵节点个数为n的完全二叉树,其最后一层的节点数量x = n - 高度为h-1的满二叉树的size,即 x = n - (2^h - 1)。而对于一棵高度为h的满二叉树,其最后一层的节点数 y = 2^h。因此可以得到左子树作为一棵高度为h-1的完全二叉树,其最后一层的节点数量为 min(x, y/2)。
因此,左子树的节点数量为高度h-2的满二叉树数量加上其最后一层的节点数量:
Lsize = 2^(h-1) - 1 + min(x, y/2) = 2^(h-1) - 1 + min(n - 2^h + 1, 2^(h-1))
其中h = floor(logn)。
B. 对于A的代码实现如下:
int get_left_size(int n){
int h = floor(log(n) / log(2));
int x = n - (int)pow(2, h) + 1;
int y = (int)pow(2, h);