簡體   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