【问题标题】:why is this recursive method work in this BST为什么这种递归方法在这个 BST 中起作用
【发布时间】:2022-11-12 22:12:57
【问题描述】:

我很难理解为什么这段代码有效

所以我们有一棵树,我们使用这种方法来计算高度

对我来说,问题是这种方法如何在没有循环的情况下计算树的总高度,或者根据我自己的理解,这只能用于 1 个节点,但我看不出如何为整个树工作没有任何类型的迭代

public int height() {
    if (isEmpty()) {
        return -1;
    }
    else {
        int leftHeight = left.height();
        int rightHeight = right.height();
        return Math.max(leftHeight, rightHeight)+1;
    }
}

【问题讨论】:

    标签: java recursion tree iteration binary-search-tree


    【解决方案1】:

    但是递归一种迭代。

    常规循环重复计算配方,即循环体,每次重复时(可能)使用循环变量的新值,直到满足停止条件。

    递归函数在每次调用时使用其参数变量的(可能)新值重复计算配方,函数的主体,直到满足基本测试条件 - 然后,前面的调用返回并继续执行它们的计算配方(s)——这是相同的配方,因为它是相同的功能——直到所有计算完成。

    从概念上讲,这是同一件事。

    具体来说,您的示例分别为每个参数树的分支调用相同的配方——计算二叉树高度的函数,它它们本身也是树,就像参数树本身一样。就像循环的主体对于所有迭代都是相同的。

    所以你的功能计算左分支的高度,将其保存在临时变量中;计算右分支的高度,将其保存在另一个临时变量中;然后结合这两个结果来产生它自己的结果。

    因此,它一遍又一遍地重复许多计算步骤。

    当特定调用遇到叶子时,这被视为基本情况。然后,此调用直接返回其结果,而不调用同一配方的任何更多实例。

    作为说明,(写作height <tree> 表示<tree>.height()),

    height { {{* 1 *} 2 *} 3 {* 4 {{* 5 *} 6 *}} }
    =
     set
      a = height {{* 1 *} 2 *}
      b = height {* 4 {{* 5 *} 6 *}}
      return max(a,b)+1
    =
     set
      a = /// height {{* 1 *} 2 *}
            set a2 = height {* 1 *}
                b2 = height *
                return max(a2,b2)+1
      b = height {* 4 {{* 5 *} 6 *}}
      return max(a,b)+1
    =
     set
      a = /// height {{* 1 *} 2 *}
            set a2 = /// height {* 1 *}
                       set a3 = height *
                           b3 = height *
                           return max(a3,b3)+1
                b2 = height *
                return max(a2,b2)+1
      b = height {* 4 {{* 5 *} 6 *}}
      return max(a,b)+1
    =
     set
      a = /// height {{* 1 *} 2 *}
            set a2 = /// height {* 1 *}
                       set a3 = -1
                           b3 = height *
                           return max(a3,b3)+1
                b2 = height *
                return max(a2,b2)+1
      b = height {* 4 {{* 5 *} 6 *}}
      return max(a,b)+1
    =
     set
      a = /// height {{* 1 *} 2 *}
            set a2 = /// height {* 1 *}
                       set a3 = -1
                           b3 = -1
                           return max(a3,b3)+1
                b2 = height *
                return max(a2,b2)+1
      b = height {* 4 {{* 5 *} 6 *}}
      return max(a,b)+1
    =
     set
      a = /// height {{* 1 *} 2 *}
            set a2 = /// height {* 1 *}
                           return max(-1,-1)+1
                b2 = height *
                return max(a2,b2)+1
      b = height {* 4 {{* 5 *} 6 *}}
      return max(a,b)+1
    =
     set
      a = /// height {{* 1 *} 2 *}
            set a2 = 0
                b2 = height *
                return max(a2,b2)+1
      b = height {* 4 {{* 5 *} 6 *}}
      return max(a,b)+1
    =
     set
      a = /// height {{* 1 *} 2 *}
            set a2 = 0
                b2 = -1
                return max(a2,b2)+1
      b = height {* 4 {{* 5 *} 6 *}}
      return max(a,b)+1
    =
     set
      a = /// height {{* 1 *} 2 *}
                return max(0,-1)+1
      b = height {* 4 {{* 5 *} 6 *}}
      return max(a,b)+1
    =
    

    继续,

    =
     set
      a = /// height {{* 1 *} 2 *}
                return max(0,-1)+1
      b = height {* 4 {{* 5 *} 6 *}}
      return max(a,b)+1
    =
     set
      a = 1
      b = height {* 4 {{* 5 *} 6 *}}
      return max(a,b)+1
    =
     set
      a = 1
      b = /// height {* 4 {{* 5 *} 6 *}}
            set a2 = height *
                b2 = height {{* 5 *} 6 *}
                return max(a2,b2)+1
      return max(a,b)+1
    =
    ...... etc.
    

    就像在每次调用之间记住外部变量的值一样一个循环的主体,属于 a 的外部调用的变量递归函数在内部调用执行其工作时被记住。

    钥匙这里是递归函数的每次调用都是复制相同的计算配方,以及它自己的一组变量,其用途由该配方规定。

    所以配方是一样的,但每个副本都是独立的、独立的、不同的。一个给定副本(即调用)使用它自己的一组函数配方的变量,并记住哪个副本被调用——所以当这个副本完成它的工作时,它的结果将被返回到那里。

    当最顶层的副本——第一个被调用的——完成时,整个工作就完成了,the final result is returned 作为整体价值。

    【讨论】:

      猜你喜欢
      • 2023-03-17
      • 1970-01-01
      • 2017-04-28
      • 2015-11-08
      • 1970-01-01
      • 1970-01-01
      • 2013-11-02
      • 1970-01-01
      相关资源
      最近更新 更多