简体   繁体   English

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

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

I am trying to compute the depth of any(not necessarily complete) BST in O(log n) time recursively. 我试图以递归方式计算O(log n)时间内任何(不一定是完整的)BST的深度。

This is the algorithm I came up with: 这是我提出的算法:

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

Is this algorithm fine for calculating depth in O(log n) time? 这个算法在O(log n)时间内计算深度是否合适?

Is there a better way? 有没有更好的办法?

That's O(n) time since you may traverse every node doing that. 这是O(n)时间,因为你可以遍历每个节点。 You can do a search on a binary search tree in O(log n) but you can't find the depth of a binary tree in anything less than O(n) unless you cache the depths as you build it or do something similar. 您可以在O(log n)中搜索二进制搜索树,但除非在构建深度或执行类似操作时缓存深度,否则无法在O(n)中找到二叉树的深度。

There are two special cases you may want to be aware of. 您可能需要注意两种特殊情况。

A perfect binary tree can have its depth determined in O(log n). 完美的二叉树可以在O(log n)中确定其深度。 This means every leaf is at the same level. 这意味着每片叶子处于同一水平。

Complete and balanced binary tree can have its depth approximated in O(log n) or in O(1) if the number of nodes is known. 如果已知节点数,则完整平衡的二叉树可以使其深度近似为O(log n)或O(1)。 This will be approximate however (+/-1 usually). 这将是近似值(通常为+/- 1)。

The only way you'll get O(log(n)) runtime is if you only examine one path, and the only way you will be able to get away with examining one path is if you know that the tree has uniform height, and this only is the case with full binary trees, which your question specifically stated is not the case. 你获得O(log(n))运行时的唯一方法就是你只检查一条路径,并且你能够通过检查一条路径的唯一方法是你知道树的高度是否均匀,这只是完整二叉树的情况,你的问题具体说明并非如此。

Therefore, there is no O(log(n)) algorithm that will determine the depth of a given binary tree. 因此,没有O(log(n))算法将确定给定二叉树的深度。

You can only find the deepest node of an unknown, unbalanced tree by looking at every leaf node, which requires traversing the lot as you are doing - O(n). 您只能通过查看每个叶节点来找到未知非平衡树的最深节点,这需要在您执行时遍历该批次 - O(n)。

As for a "better" way, you can't make it a lesser Order, but you don't need quite such complex code to achieve your result. 至于“更好”的方式,你不能使它成为一个较小的顺序,但你不需要这么复杂的代码来实现你的结果。 Here is marginally less efficient implementation (because it recurses one level deeper) which is much more readable and more robust (if you pass in a NULL root pointer it won't go pop) approach: 这是一个效率稍低的实现(因为它更深层次地递归),它更具可读性和更强大(如果传入一个NULL根指针,它将不会弹出)方法:

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

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

A problem in C is that the function stack is not dynamicaly allocated on the heap, so at one point we will run out of space. C中的一个问题是函数堆栈没有在堆上动态分配,所以在某一点上我们将耗尽空间。 Especially when each recursive call spawns two functions. 特别是当每个递归调用产生两个函数时。 In other words if your tree is somewhat balanced you will end up with log(N)^2 function calls. 换句话说,如果你的树有点平衡,你最终会得到log(N)^ 2函数调用。 If you instead iterate over the left branches and recurse on the right ones, then the stack will not grow as fast. 如果您改为迭代左侧分支并递归右侧分支,则堆栈将不会快速增长。

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

This is the way IE Quick Sort is implemented in many operating systems: 这是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 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;
}

I think comparing two integer variables takes less time than calling a function. 我认为比较两个整数变量比调用函数花费的时间更少。

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

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