【发布时间】:2021-10-31 08:14:44
【问题描述】:
如果给定总节点,我想在完整二叉树的左右子树中查找节点数,
例如,
n = 5 ===> 左 -> 3 右 -> 1
n = 8 ===> 左 -> 4 右 -> 3
其中n是二叉树中节点的总数
是否有任何公式或 O(1)/最佳解决方案可以做到这一点?
【问题讨论】:
标签: binary-tree binary-search-tree
如果给定总节点,我想在完整二叉树的左右子树中查找节点数,
例如,
n = 5 ===> 左 -> 3 右 -> 1
n = 8 ===> 左 -> 4 右 -> 3
其中n是二叉树中节点的总数
是否有任何公式或 O(1)/最佳解决方案可以做到这一点?
【问题讨论】:
标签: binary-tree binary-search-tree
是否有任何公式或 O(1)/最佳解决方案可以做到这一点?
是的。
将给定的?(节点数)用二进制记数法写出,除最重要的 1 外,每个 1 都变为 0。将此数称为 ?。将 ? 定义为 ? - ?,以便在二进制中它与 ? 相同,但删除了它的最高有效数字。 右子树中的节点数将等于 max(?, ? / 2 − 1)。
然后知道 left 子树中有多少是小菜一碟,因为两个子树中的节点总和加上 1(对于根节点)必须等于 ?。
当 ? = 5 时,我们将二进制记为 0b101。我们可以看到? = 0b100 和? = 0b001。所以右子树有 max(?, ?/2 − 1) 个节点,即 max(1, 1) = 1。左子树有剩余节点,即 3,因此 3 + 1 + 1(对于根)= 5.
这是一个表格,其中包含 1 到 15 之间 ? 的结果:
| ? | in binary | ? | ? | ?/2 − 1 | in right subtree = max(?, ?/2 − 1) | in left subtree |
|---|---|---|---|---|---|---|
| 1 | 0b1 | 0b1 | 0b0 | 0b0 | 0 | 0 |
| 2 | 0b10 | 0b10 | 0b0 | 0b0 | 0 | 1 |
| 3 | 0b11 | 0b10 | 0b1 | 0b1 | 1 | 1 |
| 4 | 0b100 | 0b100 | 0b00 | 0b1 | 1 | 2 |
| 5 | 0b101 | 0b100 | 0b01 | 0b1 | 1 | 3 |
| 6 | 0b110 | 0b100 | 0b10 | 0b1 | 2 | 3 |
| 7 | 0b111 | 0b100 | 0b11 | 0b1 | 3 | 3 |
| 8 | 0b1000 | 0b1000 | 0b000 | 0b11 | 3 | 4 |
| 9 | 0b1001 | 0b1000 | 0b001 | 0b11 | 3 | 5 |
| 10 | 0b1010 | 0b1000 | 0b010 | 0b11 | 3 | 6 |
| 11 | 0b1011 | 0b1000 | 0b011 | 0b11 | 3 | 7 |
| 12 | 0b1100 | 0b1000 | 0b100 | 0b11 | 4 | 7 |
| 13 | 0b1101 | 0b1000 | 0b101 | 0b11 | 5 | 7 |
| 14 | 0b1110 | 0b1000 | 0b110 | 0b11 | 6 | 7 |
| 15 | 0b1111 | 0b1000 | 0b111 | 0b11 | 7 | 7 |
【讨论】: