如何证明堆数据结构中的子节点位于:2 * n和2 * n + 1?

时间:2014-08-08 12:43:45

标签: tree binary-tree heap

这不是功课问题,我今天学习了堆数据结构,我不知道如何证明关系是真的。感谢。

2 个答案:

答案 0 :(得分:4)

归纳证明:

  1. 根(1)的孩子 - > child1 = 2 * 1 = 2,child2 = 2 * 1 + 1 = 3 true
  2. 假设第k个元素的子元素是 - > child1 = 2k,child2 = 2k + 1
  3. 证明第(k + 1)个元素的子元素是child1 = 2 *(k + 1),child2 = 2(k + 1)+ 1(证明这一点)
  4. 证明3: 因为第k个元素的子元素是2k和2k + 1(基于假设),所以接下来的两个元素是2k + 2和2k + 3。

    2k + 2 = 2(k + 1)(k + 1的第一个孩子被证明)(a)

    2k + 3 = 2k + 2 + 1 = 2(k + 1)+ 1(k + 1的第二个孩子被证明)(b)

    来自(a)& (b) - >因此3是有效的,因此元素n的子元素是2n和2n + 1

答案 1 :(得分:1)

这是一个没有归纳的证明,从我的角度来看,它更直观,更有洞察力。 以下是证明这种关系的4个心理步骤。

展平树。

让我们按以下方式枚举树的所有顶点:
enter image description here

以下是这些错误在数组中的显示方式:

enter image description here

隔离数组中的兄弟姐妹。

我们可以注意到,每两个连续节点(第一个节点除外)是一些常见顶点的子节点:
1 [ 2 3 ] [ 4 5 ] [ 6 7 ] [ 8 9 ]

以不同方式构建此数组。

现在让我们以相反的顺序思考。如果我们有一对数组怎么办:[(2,3),(4 5),(6,7),(8,9)]我们想把它们聚合在一个数组中?

假设我们已经放置了前3对:
[ 2 3 ] [ 4 5 ] [ 6 7 ]

最终数组中数字8的索引是什么? 我们知道我们已经放了3对,他们在开始时已经取得了3 * 2 = 6个位置,所以我们将占据第7位。

如果我们编码对的位置,它将如下所示:

artistSongs

关键部分是数组聚合 [2 * i] 的索引。在这段代码中,很明显我们为什么会乘以 2 - 我们这样做,因为我们必须跳过之前的 i - 1

结合树的扁平化和对的聚合

现在我们需要看到构建对的聚合数组和二叉树的展平之间的对应关系。每对兄弟姐妹都有父母。如果两个兄弟姐妹(2,3)和(4,5)在阵列中相邻,那么他们的父母也是相邻的。兄弟姐妹(2,3)有父1,兄弟姐妹(4,5)有父2,兄弟姐妹(6,7)有父3.所以父对象就像这个对数组中的索引 { {1}}当我们使用 2 * i 访问其左边的孩子时,我们可以想到跳过 i - 1 生成的子项对按先前的顶点。