【问题标题】:Logic of to find height of tree by recursion递归求树高的逻辑
【发布时间】:2017-08-21 08:41:26
【问题描述】:

我试图找到一棵树的高度。这是我在网上找到的一些代码。但是,我不明白它是如何工作的。如果您能解释一下这个程序是如何工作的,我将不胜感激。

#include <stdio.h>
#include <stdlib.h>

struct n {
    int data;
    struct n *left;
    struct n *right;
};

typedef struct n node;

int height_of_tree(node *root) {
    if (root == NULL) return -1; // Why doesn't the function break here?
    int leftTree  = height_of_tree(root->left); 
    int rightTree = height_of_tree(root->right);
    if (leftTree > rightTree) return leftTree + 1;
    else return rightTree + 1;
}

node *getNewNode(int data) {
    node *newNode  = (node *) malloc(sizeof(node));
    newNode->data  = data;
    newNode->left  = NULL;
    newNode->right = NULL;
    return newNode;
}

node *insert(node *root, int data) {
    if (root == NULL) root = getNewNode(data);
    else if (data <= root->data)
         root->left  = insert(root->left,  data);
    else root->right = insert(root->right, data);
    return root;
}

int main() {
    node *root = NULL;
    root = insert(root, 12);
    root = insert(root, 23);
    root = insert(root, 122);
    root = insert(root, 1);
    root = insert(root, 2);
    root = insert(root, -3);
    root = insert(root, -4);

    printf("%d\n", root->right->data);
    printf("%d\n", height_of_tree(root));
}

为什么height_of_tree 函数没有返回?

【问题讨论】:

  • 我编辑了您的答案以使其更好。但是,我无法理解您所问的很多内容。如果我的编辑以您不希望的任何方式更改了您的原始问题,请告诉我。
  • 原始问题没有改变,感谢您的编辑。你能解释一下这个程序是如何工作的吗?
  • 如果您对程序的哪些部分您不了解,会更有帮助!
  • 一个名为 height_of_tree 的函数。我不明白它是如何工作的
  • 那么你理解 insert() 函数和 getNewNode() 对吗?

标签: recursion logic binary-search-tree


【解决方案1】:

首先,要明确一点,您的程序是找到a binary tree 的高度,其中每个节点最多有 2 个子节点(左和/或右)

所以递归函数height_of_tree(node *root)背后的基本思想是,从树的根开始,我们将找到并比较它的左节点和右节点的height

要找到左节点(或右节点)的高度,我们假设左节点及其所有子节点将作为子树独立存在,并且节点本身就是根。我们开始在这样的子树上再次运行height_of_tree,以左节点为新根(这就是我们称之为递归的原因)。同样的逻辑也适用于右节点:

// Reuse height_of_tree() to find the heights of the left node and the right node
// leftTree here means left tree's height
int leftTree  = height_of_tree(root->left); 
int rightTree = height_of_tree(root->right);

然后我们开始比较:如果左节点的高度 > 右节点的高度,那么根(或它们的父节点)的左节点的高度 + 1。反之亦然,如果右节点的高度 > 左节点的高度高度,那么根的正确节点的高度+1:

if (leftTree > rightTree) return leftTree + 1;
else return rightTree + 1;

最后,条件检查if (root == NULL) return -1; 是检查何时停止向下并寻找子树(因为它下面没有更多节点或者我们可以说节点== NULL)。在执行其他代码行之前,我们必须先检查这一点,因为if (root == NULL),那么我们肯定没有下一个左/右孩子。

一些例子:

1) 当树的字面意思为 = NULL 时,height_of_tree 将返回 -1。

node *root = NULL;
printf("%d\n", height_of_tree(root)); // Print out -1

2) 当树只有一个节点,也就是根节点时,height_of_tree 将返回 0。(请注意,根据定义,只有一个根节点的树的高度为 0)

node *root = NULL;
root = insert(root, 12);
printf("%d\n", height_of_tree(root)); // Print out 0

3) 当树只有两个节点,即根节点和一个子节点时,height_of_tree 将返回 1。

node *root = NULL;
root = insert(root, 12); // root with value = 12
root = insert(root, 23); // right child because its value 23 > root's value 12 
printf("%d\n", height_of_tree(root)); // Print out 1

这第三种情况我会详细说明:

  • 首先,我们将从树根开始,即 12。
  • 因为根不为NULL,我们开始求其左孩子的高度:int leftTree = height_of_tree(root-&gt;left);
  • 由于左孩子为NULL,函数height_of_tree(root-&gt;left)在执行时将返回-1,从而使int leftTree = -1
  • 然后,我们开始求其右孩子的高度:int rightTree = height_of_tree(root-&gt;right);
  • 右节点现在变成一棵只有一个节点的新树,根据上面的例子#2,我们有一个只有一个节点的树的高度=0,因此int rightTree = 0
  • 最后,比较 leftTree 和 rightTree,我们发现 rightTree 更高,因此根的高度将是 rightTree + 1(其最高子节点的高度 + 1)。结果,根的高度为 = rightTree + 1 = 1

希望这会有所帮助!

【讨论】:

  • 非常感谢,真的很有帮助,也很详细。你是最棒的!
猜你喜欢
  • 2012-12-12
  • 2012-08-02
  • 2019-12-16
  • 2016-09-19
  • 1970-01-01
  • 2017-07-13
  • 1970-01-01
  • 2021-07-20
  • 1970-01-01
相关资源
最近更新 更多