Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 查找任意(不一定完全)二叉树深度的递归方法_C_Data Structures_Tree - Fatal编程技术网

C 查找任意(不一定完全)二叉树深度的递归方法

C 查找任意(不一定完全)二叉树深度的递归方法,c,data-structures,tree,C,Data Structures,Tree,我试图递归地计算O(logn)时间内任何(不一定完全)BST的深度 这就是我提出的算法: //max() - returns the max of two numbers int depth(root) { if(root->left==NULL && root->right==NULL) //leaf return 0; else if(root->left!=NULL && root->right==NU

我试图递归地计算O(logn)时间内任何(不一定完全)BST的深度

这就是我提出的算法:

//max() - returns the max of two numbers
int depth(root)
{
    if(root->left==NULL && root->right==NULL) //leaf
        return 0;
    else if(root->left!=NULL && root->right==NULL) //with right leaf
        return( max(depth(root->left),0)+1);
    else if(root->left==NULL && root->right!=NULL) //with left leaf
        return( max(0,depth(root->right)+1);
    else if(root->left->left==NULL && root->left->right==NULL && root->right->left==NULL&&root->right->right==NULL) // this a parent of two leaves
        return 1; 
    else// for the condition that this a parent of two sub roots
        return( max(depth(root->right),depth(root->left))+1);
}
这个算法适合计算O(对数n)时间内的深度吗

有更好的方法吗?

这是O(n)时间,因为您可以遍历每个节点来执行此操作。您可以在O(logn)中的二叉搜索树上进行搜索,但在O(n)以下的任何地方都找不到二叉树的深度,除非您在构建二叉树时缓存深度或执行类似操作

您可能需要注意两种特殊情况

一个完美的二叉树可以用O(logn)来确定其深度。这意味着每片叶子都处于同一水平

如果节点数已知,则完全平衡二叉树的深度可以近似为O(logn)或O(1)。但是,这将是近似值(+/-1)。

获得O(log(n))运行时的唯一方法是只检查一条路径,而检查一条路径的唯一方法是知道树的高度是一致的,这仅适用于完整的二叉树,你的问题具体说明的情况并非如此


因此,没有O(log(n))算法可以确定给定二叉树的深度。

通过查看每个叶节点,您只能找到未知、不平衡树中最深的节点,这需要像您所做的那样遍历地块-O(n)

至于一种“更好”的方法,您不能将其简化,但您不需要非常复杂的代码来实现您的结果。这是一种效率稍低的实现(因为它递归更深一层),更具可读性和更健壮(如果传入空根指针,它将不会弹出)的方法:

int depth(root)
{
    if (root == NULL)
        return(0);

    return(1 + max(depth(root->left), depth(root->right)));
}

C语言中的一个问题是,函数堆栈没有在堆上动态分配,因此在某一点上我们会耗尽空间。尤其是当每个递归调用产生两个函数时。换句话说,如果你的树是平衡的,那么你将得到log(N)^2个函数调用。如果在左分支上迭代,在右分支上递归,那么堆栈的增长速度就不会那么快

int
depth(struct bt *root, int dl)
{
        int dr, dmr;

        for(dmr=dr=dl; root != NULL; dl++){
                if((dr = depth(root->right, dl+1)) > dmr) 
                        dmr = dr;
                root = root->left;
        }
        return(dl > dmr ? dl : dmr);
}
这就是在许多操作系统中实现快速排序的方式:


我认为比较两个整数变量比调用函数花费的时间要少。

Nope。想想一个二叉树的例子,它(递归地)只有一个子树(它看起来非常类似于链表)。在二叉树中查找深度是O(n),除非树具有某种强制属性(例如平衡)。我猜“完全”是指“平衡”:-@Jason:是的,这个术语不精确-根据维基百科,我说的是“完美”二叉树。在任何情况下,如果你知道二叉树的高度+/-1,那么你也可以对一棵完整的树使用O(log(n))算法。@Kyle:Ooops,用错误的术语纠正了你。多么尴尬:-)是的,我的意思是完美。(自我提示:发帖前多睡一会儿)谢谢。递归可能是一件美妙的事情——只要不断地切分,直到找到最简单的形式。
int maxDepth(BST *root)
{
    int ldepth=0,rdepth=0,maxdepth=0;

    if(root==NULL)
      return(0);

    ldepth=maxDepth(root->left);
    rdepth=maxDepth(root->right);

    maxdepth=MAX(ldepth,rdepth);
    return(maxdepth+1);   

}
int TreeDepthRec(Tree *pt){
  if(!*pt)
      return 0;
  int a = TreeDepthRec(&(*pt)->left);
  int b = TreeDepthRec(&(*pt)->right);
  return (a>b)? 1+a : 1+b;
}