【问题标题】:Proving tree is balanced from subtrees's balancedness从子树的平衡性证明树是平衡的
【发布时间】:2015-05-25 09:04:06
【问题描述】:

我正在解决“Cracking the Coding Interview”中的以下问题:实现一个函数来检查二叉树是否平衡。平衡树是一棵树,使得任何节点的两个子树的高度都不会相差超过 1。

本书的示例解决方案(复制如下)假设从节点发出的树是平衡的,如果 (a) 节点的左子树和右子树是平衡的; (b) 节点本身是平衡的。我试图理解为什么会这样?上述两个条件的满足如何证明从节点发出的整棵树是平衡的?

谢谢

public static boolean isBalanced(TreeNode root)
{
    if (checkHeight(root)==-1)
        return false;
    return true;
}


public static int checkHeight(TreeNode root)
{
    //base case
    if (root == null)
        return 0;

    //is left subtree balanced
    int leftHeight = checkHeight(root.leftChild);

    if (leftHeight == -1)
        return -1;

    //is right subtree balanced
    int rightHeight = checkHeight(root.rightChild);

    if (rightHeight == -1)
        return -1;

    //is current node balanced
    int heightDiff = leftHeight - rightHeight;

    if (Math.abs(heightDiff) > 1)
        return -1;

    return (Math.max(leftHeight, rightHeight) + 1);
}

【问题讨论】:

  • 为什么没人说Induction?
  • @kutschkem 您能否解释一下,或者指出一个用于证明平衡性的归纳示例?谢谢!

标签: java tree binary-tree tree-balancing


【解决方案1】:

这是递归的应用——例程计算被检查节点的左右子树的高度,同时递归地验证子树。如果发现任何不平衡的节点或子树高度正常,则返回-1。子树高度的比较决定了当前节点是否平衡。

顺便说一句,在整个 checkHeight() 函数中将 root 替换为 currnode 以明确例程如何递归地应用于树中的每个节点,而不仅仅是其根。

【讨论】:

    【解决方案2】:

    平衡二叉树是左右子树的总深度相差不超过一个[1]。这里提出的解决方案是递归的,首先检查孩子自己是否平衡,然后检查父母是否平衡。它通过检查孩子的左右子树的深度来做到这一点,如果它们之间的深度最多相差 1,则返回max(left_depth,right_depth)+1。如果不是,则返回-1。然后该算法对整个树继续此操作。如果任意点的深度为 -1(表明子树不平衡),则子树的总深度返回为 -1。最后,只需检查树的总深度是否为 -1:如果是,则树不平衡,否则,它是。

    这是归纳形式的算法:

    • 基本情况

      叶节点 - 平凡平衡,有 0 个子节点。它返回 1,因为 深度将包括孩子的数量(0)以及 节点本身。

    • 归纳案例

      一个中间节点,如果孩子们是平衡的 平衡,并且左孩子的深度与右孩子的深度最多相差1。 如果平衡,则返回max(left_depth,right_depth) + 1,代表树的总深度, 包括节点本身。如果不平衡,只需返回-1

    • 终于

      根节点,检查类似于归纳情况,但如果平衡,则 整棵树是平衡的,总深度为max(left_depth,right_depth) + 1,其中left_depthright_depth代表左/右子树相对于根节点的深度。

    可以在here 找到之前提出的 SO 问题,该问题涵盖了编写 BST 的几个非常有趣的方面。

    【讨论】:

    • 感谢 aspiring_sarge。如果“孩子是平衡的,并且左孩子的深度等于右孩子的深度”,您能否解释一下您的答案部分,即中间节点将是平衡的。有证据吗?
    • @randomUser47534:对不起。我的回答有误。如果孩子是平衡的,左孩子的深度不等于右孩子的深度,但最多相差一个。这源于定义 BST 平衡的方式——根据我引用的链接 [1],平衡 BST 是左右节点的高度差不超过 1,所以这源于定义。然后简单地在树上递归,从叶子开始,以确保这个定义在每个点都成立。
    • 第一句话混淆了体重平衡和身高平衡。 OP 和您的答案谈论身高平衡,但您的第一句话定义了体重平衡。
    【解决方案3】:

    既然你问了,这里再介绍一些归纳:

    https://en.wikipedia.org/wiki/Well-founded_relation

    忘记你所知道的关于感应的一切,这是真实的。如果我们有一些关系 R,当且仅当不存在无限下降链 x1,x2,x3,... 与 x1 R x2,x2 R x3 等等时,R 被称为是有根据的。 (“降序”是因为人们在考虑

    例如,

    有了良好的关系,你就有了

    (对于所有 x : (对于所有 y : x R y -> P(y)) -> P(x)) 对于所有 x : P(x)

    换句话说,证明所有最小元素 wrt 就足够了。 R 有一些性质,然后证明如果所有比一些 x 小的元素都满足 P,那么 x 也满足。

    特例是你可能知道的归纳法:

    (P(0) & for all n: P(n) -> P(n+1)) -> for all n: P(n) (这里有根据的关系是后继函数)

    对于有限树,子树关系(显然)是有根据的,所以我们可以这样做(实际上让我们使用传递闭包,使证明更短。它仍然是有根据的):

    基本情况:(叶子,这些是最小的 wrt 子树关系) 有 0 个孩子的叶子是平衡的,很简单

    感应: 假设所有子树(及其子树等)都是平衡的,并且根节点是平衡的,所有节点都是平衡的,没有剩余的节点可能是不平衡的(看看我在这里做了什么?)

    如果我们还注意到平衡意味着子树是平衡的,我们可以不使用传递闭包来完成此操作。那么我们可以说直接子树平衡意味着它们的所有子树也都是平衡的,我们回到我的证明。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-18
      • 2014-01-29
      • 1970-01-01
      • 2011-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多