繁体   English   中英

一种递归方法,用于查找任何(不一定是完整的)二叉树的深度

[英]A recursive method to find depth of a any(not necessarily complete) Binary tree

我试图以递归方式计算O(log n)时间内任何(不一定是完整的)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(log n)时间内计算深度是否合适?

有没有更好的办法?

这是O(n)时间,因为你可以遍历每个节点。 您可以在O(log n)中搜索二进制搜索树,但除非在构建深度或执行类似操作时缓存深度,否则无法在O(n)中找到二叉树的深度。

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

完美的二叉树可以在O(log n)中确定其深度。 这意味着每片叶子处于同一水平。

如果已知节点数,则完整平衡的二叉树可以使其深度近似为O(log n)或O(1)。 这将是近似值(通常为+/- 1)。

你获得O(log(n))运行时的唯一方法就是你只检查一条路径,并且你能够通过检查一条路径的唯一方法是你知道树的高度是否均匀,这只是完整二叉树的情况,你的问题具体说明并非如此。

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

您只能通过查看每个叶节点来找到未知非平衡树的最深节点,这需要在您执行时遍历该批次 - O(n)。

至于“更好”的方式,你不能使它成为一个较小的顺序,但你不需要这么复杂的代码来实现你的结果。 这是一个效率稍低的实现(因为它更深层次地递归),它更具可读性和更强大(如果传入一个NULL根指针,它将不会弹出)方法:

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);
}

这是IE Quick Sort在许多操作系统中实现的方式:

http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdlib/qsort.c?rev=1.10;content-type=text%2Fx-cvsweb-markup

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;
}

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

暂无
暂无

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

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