二叉树深度

时间:2017-05-04 21:34:37

标签: c++ recursion binary-tree

试图找到二叉搜索树的深度。做了一些谷歌搜索,但我的代码崩溃了:

int treeDepth(int depth) const
        {
            int l = this->left->treeDepth(depth);
            int d = this->right->treeDepth(depth);

            return depth + std::max(l, d);
        }

使用以下内容调用此函数:root->treeDepth(1);

4 个答案:

答案 0 :(得分:1)

首先,我认为您可能会将树的深度与树的 height 混淆。有关说明,请参阅What is the difference between tree depth and height?

例如,以下是此(二进制)树中节点的深度和高度('0'是根):

    0     -- depth 0, height 2
   / \
  1   2   -- depth 1, height 1 and 2, respectively, for nodes 1 and 2
 / \
3   4     -- depth 2, height 0

如您所见,树根的深度为“0”,即O(1)计算。然而,树的高度在递归方面更有趣,可以使用以下方法计算:

struct TreeNode {
    T _value;
    typedef TreeNode* node_ptr;    
    node_ptr _left, _right;
};
...
int treeHeight(Node* node)
{
    return std::max(node->_left? 1 + height(node->_left) : 0,
                    node->_right? 1 + height(node->_right) : 0);
}
...
std::cout << treeHeight(root);
...

基本理念是这样的: 在递归(深度优先)遍历期间,如果到达叶节点,则返回值“0”(这是每个叶节点的高度)。否则,计算以非叶子节点为根的树的高度(这是左子树的高度的最大值和该节点的右子树+节点本身的1)。从树的 root 开始。

我想在您的问题中解决的第二方面是关于我从您的功能签名中收集的内容:

int treeDepth(int depth) const

以及你打电话的方式:

root->treeDepth(1);

树的深度有助于成为 root 的属性。相反,它是树的属性,由树节点组成,其中一个是 root 节点。所以,我将如下定义类(此处显示的C ++结构):

template<class T>
struct BinaryTree {
    struct TreeNode {
        T _value;
        typedef TreeNode* node_ptr;    
        node_ptr _left, _right;
    };
    TreeNode _root_node;
    typedef typename TreeNode::node_ptr node_ptr;
    node_ptr _root;
    ...
    int height(node_ptr node) const;
    ...
};

最后,在树中找到给定节点深度

int depth(node_ptr node) const;
// returns depth of node if it is in the tree, else -1

是一个可以应用递归的问题。但是,递归方法并不自然,广度优先(或水平顺序)遍历将更适合此。

答案 1 :(得分:0)

你需要阅读一些关于递归的内容。

递归的一个基本原则是必须有一个&#34;停止条件&#34;这将在某个时候终止递归。

否则,您将拥有所谓的&#34;失控递归&#34;,您的堆栈已填满,您的程序崩溃并烧毁。

在您的情况下,&#34;停止条件&#34;将达到this->leftthis->right,恰好为NULL。

所以,对于未来的读者(正如Barmar在评论中所建议的那样)

int l = left == NULL? 0 : left->treeDepth(depth);
int d = right == NULL? 0 : right->treeDepth(depth);

答案 2 :(得分:0)

您的代码中确实存在许多问题。

实现递归终止所需的全部拳头,这是阻止你的函数永远调用自己所需的条件 在你的情况下,你需要写一些像 if(left==nullptr && rigth==nullptr) return depth;

递归终止非常重要!在编写递归函数时总是需要它。没有你100%进入一个永无止境的循环(在最好的情况下)。

然后,当您重新调用函数时,需要更改深度值 我的意思是,如果你在树的另一个节点上下来,这意味着树高至少“深度+ 1”,所以你需要传递深度+1而不仅仅是深度, 在函数和函数中只需编写

return std::max(l,d);

另外,你正在使用指针,总是写一个条件来检查你是否真的想要访问一个定义良好的地址,也就是说,甚至在尝试访问一个地址之前(例如这个 - >左)你需要写一个类似if( this->left!=nullptr)的条件(nullptr来自c ++ 11,否则NULL也会完成工作)

答案 3 :(得分:0)

尝试这样的事情:

int treeDepth() const
        {
            int l = left == NULL? 0 : left->treeDepth();
            int d = right== NULL? 0 : right->treeDepth();
            return 1 + std::max(l, d);
        }

在这种情况下,您不需要额外的参数&#34;深度&#34;