繁体   English   中英

二叉树深度

[英]Binary tree depth

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

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);调用此函数root->treeDepth(1);

首先 ,我认为您可能将树的深度与树的高度混淆了。 请参阅树的深度和高度之间的区别是什么? 进行解释。

例如,以下是此(二进制)树中节点的深度和高度(“ 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)。 从树的开始。

我要在您的问题中解决的第二个方面是关于我从函数签名中收集的内容:

int treeDepth(int depth) const

以及调用方式:

root->treeDepth(1);

树的深度利于的特性。 相反,它是树,它由树节点,其中之一是根节点的一个属性。 因此,我将如下定义类(此处显示的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

是您可以应用递归的问题。 但是,递归方法并不自然,因此广度优先(或级别顺序)遍历将更适合于此。

您需要阅读一些有关递归的知识。

递归的基本原则之一是必须有一个“停止条件”,该条件将在某个时候终止递归。

否则,您将拥有所谓的“失控递归”,堆栈将被填满,并且程序将崩溃并刻录。

在您的情况下,“停止条件”将达到this->leftthis->right ,而恰好为NULL。

因此,对于未来的读者(如Barmar在评论中所建议)

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

您的代码中实际上有很多问题。

首先,您需要实现递归终止,这是阻止函数永久调用其自身的条件,您需要编写类似if(left==nullptr && rigth==nullptr) return depth;

递归终止非常重要! 在编写递归函数时,总是需要它。 如果没有,您将百分百陷入永无止境的循环(在最佳情况下)。

然后,当您重新调用函数时,您需要更改深度值,我的意思是,如果您在树的另一个节点上下降,则意味着树至少高到“ depth + 1”,因此您需要传递depth + 1不仅是深度,而且在函数的和处都可以写

return std::max(l,d);

另外,您在使用指针时,请始终编写条件以检查您是否确实在尝试访问定义明确的地址,也就是说,在尝试访问地址(例如this-> left)之前,您还需要编写一个像if( this->left!=nullptr) (来自c ++ 11的nullptr ,否则NULL也将完成工作)

尝试这样的事情:

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

在这种情况下,您不需要额外的“深度”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM