计算树的高度

时间:2010-02-17 08:07:49

标签: c++ data-structures binary-search-tree

我正在尝试计算树的高度。我对下面的代码不感兴趣。

#include<iostream.h>

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

typedef struct tree tree;

class Tree
{
private:
    int n;
    int data;
    int l,r;
public:
    tree * Root;
    Tree(int x)
    {
        n=x;
        l=0;
        r=0;
        Root=NULL;
    }
    void create();
    int height(tree * Height);

};

void Tree::create()
{
    //Creting the tree structure
} 

int Tree::height(tree * Height)
{
    if(Height->left==NULL && Height->right==NULL)
    {return 0;
    }
    else
    {
        l=height(Height->left);
        r=height(Height->right);

        if (l>r)
        {l=l+1;
        return l;
        }
        else
        {
            r=r+1;
            return r;
        }
    }
}

int main()
{
    Tree A(10);//Initializing 10 node Tree object
    A.create();//Creating a 10 node tree

    cout<<"The height of tree"<<A.height(A.Root);*/

}

它给了我正确的结果。 但是在some posts(谷歌搜索页面)建议进行后序遍历并使用此高度方法来计算高度。有什么特别的原因吗?

5 个答案:

答案 0 :(得分:15)

但这不是一个后期遍历正是你在做什么?假设left和right都是非null,则首先执行height(left),然后执行height(right),然后在当前节点中进行一些处理。根据我的说法,这是后序遍历。

但我会这样写:

int Tree::height(tree *node) {
    if (!node) return -1;

    return 1 + max(height(node->left), height(node->right));
}

编辑:根据您定义树高的方式,基本情况(对于空树)应为0或-1。

答案 1 :(得分:4)

代码将在树中失败,其中至少有一个节点只有一个子节点:

// code snippet (space condensed for brevity)
int Tree::height(tree * Height) {
    if(Height->left==NULL && Height->right==NULL) { return 0; }
    else {
        l=height(Height->left);
        r=height(Height->right);
//...

如果树有两个节点(根和左子或右子)调用root上的方法将不满足第一个条件(至少有一个子树非空),它将递归调用两个孩子。其中一个是null,但它仍然会取消引用空指针来执行if

正确的解决方案是Hans在此处发布的解决方案。无论如何,你必须选择你的方法不变量:你允许调用哪个参数为null并且你正常处理它,否则你需要参数为非null并保证你不用空指针调用该方法

如果您不控制所有入口点(该方法在代码中是公共的),则第一种情况更安全,因为您无法保证外部代码不会传递空指针。第二个解决方案(将签名更改为引用,并使其成为tree类的成员方法)如果可以控制所有入口点,则可以更清晰(或不是)。

答案 2 :(得分:2)

树的高度不会随着遍历而改变。它保持不变。它是根据遍历而变化的节点序列。

答案 3 :(得分:2)

来自wikipedia的定义。

  

预订(深度优先):

     
      
  1. 访问root。
  2.   
  3. 遍历左子树。
  4.   
  5. 遍历正确的子树。
  6.         

    按顺序(对称):

         
        
    1. 遍历左子树。
    2.   
    3. 访问root。
    4.   
    5. 遍历正确的子树。
    6.         

      后序:

           
          
      1. 遍历左子树。
      2.   
      3. 遍历正确的子树。
      4.   
      5. 访问root。
      6.   

定义中的“访问”意味着“计算节点的高度”。在你的情况下,它是零(左和右都是空)或1 +儿童的组合高度。

在您的实现中,遍历顺序无关紧要,它会产生相同的结果。如果没有链接到你的消息来源,那么你真的可以告诉你更多的事情,说明后期订购是更喜欢的。

答案 4 :(得分:0)

以下是答案:

int Help :: heightTree (node *nodeptr)
{
    if (!nodeptr)
        return 0;
    else
    {
        return 1 + max (heightTree (nodeptr->left), heightTree (nodeptr->right));
    }
}