C ++中的二叉树基础知识

时间:2012-03-13 01:47:31

标签: c++ binary-tree

我有一个二进制树数据结构:

//Declare Data Structure
struct CP {
    int id;         //ID of the Node
    int data;       //Data of the Node
    CP * left;      //Pointer to the Left Subtree 
    CP * right;     //Pointer to the Right Subtree
};

typedef CP * CPPtr; 

在不更改树结构的情况下,如果给定节点ID,如何实际计算深度。 (id是每个树节点的唯一指示符)

7 个答案:

答案 0 :(得分:1)

您的代码缺少一些基本步骤或必要的初始化。

 BTree_Helper(BTree *Tree){// this is roughly written like pseudo code
    if(TLeft == NULL && TRight == NULL){
      depth of tree = 0 ;       
    }
    else if (TLeft == NULL){
      depth of tree = depth of right tree ;       
    }
    else if(TRight==NULL){
      depth of tree = depth of left tree;        
    }
    else{
      depth of tree = the maximum between depth of left and depth of right;
    }
 }

我刚刚给出了一些你的戒律的提示。 仔细考虑并尝试尽可能多的测试套件。

答案 1 :(得分:0)

了解基本的树/图搜索算法:breadth-first search(BFS)和depth-first search(DFS)。尝试以递归方式和明确的stack<T>实现DFS。使用queue<T>实现BFS。

注意您的方法的效率。如果要重复查找节点的深度,在某种查找表中存储树中每个节点的深度可能要快得多。理想情况下,散列表只有map<T1, T2>才能在大多数情况下完成。

您将从上述练习中学到很多东西。祝你好运!

答案 2 :(得分:0)

关于y26jin的建议,也许是这样的?

BTree_Helper(CP *TreeNode) {
    CP *TLeft = TreeNode->left;
    CP *TRight = TreeNode->right;
    if(TLeft == NULL && TRight == NULL){
      return 0;       
    }
    else if (TLeft == NULL){
      return 1+(BTree_Helper(TRight));       
    }
    else if(TRight==NULL){
      return 1+(BTree_Helper(TLeft));        
    }
    else{
      return 1+max(BTree_Helper(TLeft),BTree_Helper(TRight));
    }
 }

我现在无法真正测试代码,抱歉,如果我离开这里的话。但我觉得这些方面应该有用。

答案 3 :(得分:0)

我将假设id是树的搜索键。换句话说,左子树上任何节点的id小于此节点的id,右子树上任何节点的id都大于id 1}}这个节点。此外,id被假定为唯一。

要查找具有给定ID的节点,给定指向树的根节点的指针,您只需执行以下操作:

CP* find(CP* root, int searchID)
{
    // Starting point.
    CP* node = root;
    while(node)
    {
        // Search hit?
        if(node->id == searchID)
            return node;
        // Turn left or right?
        if(node->id < searchID)
            node = node->left;
        else
            node = node->right;
    }
    return 0; // No node with the given ID found.
}

查找深度是对此函数的简单修改:您不必返回节点,而是计算下降的级别数。深度为0表示根节点是您想要的;深度为1表示左或右节点; 2的深度意味着他们的直接孩子等等。所以你必须循环多少次:

int depth(CP* root, int searchID)
{
    // Starting point.
    CP* node = root;
    int depth = 0;
    while(node)
    {
        // Search hit?
        if(node->id == searchID)
            return depth;
        // Descending a level...
        ++depth;
        // Turn left or right?
        if(node->id < searchID)
            node = node->left;
        else
            node = node->right;
    }
    return -1; // No node with the given ID found.
}

请注意“未找到”的特殊值-1。

答案 4 :(得分:0)

我建议在该节点中存储节点子树的深度。然后,您可以在向其添加节点时更新树的深度。无论何时添加节点,退出树,在出路时沿着路径更新每个节点的深度。如果在任何时候,节点的修改子树的新深度不大于节点的其他子树的深度,则可以短路。

这种方法的好处是:

  1. 最糟糕的表现是O(log n)(假设树是平衡的)。
  2. 非递归地编写非常容易

答案 5 :(得分:0)

您可以使用递归计算任何节点的深度:

int countChildren(CPPtr node) {

    if ( node != null )
        return 1 + countChildren(node->left) + countChildren(node->right);

    else 
        return 0;

}

答案 6 :(得分:-1)

你必须将指针传递给lDepth和rDepth,而不是像值本身一样:

nodeDepth_Helper(tree,id, &lDepth, &rDepth);

此外,我认为nodeDepth_helper的参数应该被声明为int的指针:

void nodeDepth_Helper(CPPtr tree, int id, int* lDepth,int* rDepth)

在整个过程中进行这些更改可以解决您的问题。