編程之美:求二叉樹中節點的最大距離


1.問題描述

寫一個程序求一棵二叉樹相距最遠的兩個節點之間的距離

如下圖:

 

2.分析與解法

對於任意一個節點,以該節點為根,假設這個根有k個孩子節點,那么距離最遠的兩個節點U與V之間的路徑與這個根節點的關系有兩種。

1).若路徑經過Root,則U和V屬於不同子樹的,且它們都是該子樹中到根節點最遠的節點,否則跟它們的距離最遠相矛盾

2).如果路徑不經過Root,那么它們一定屬於根的k個子樹之一,並且它們也是該子樹中相距最遠的兩個頂點

因此,問題就可以轉化為在字數上的解,從而能夠利用動態規划來解決。

設第K棵子樹中相距最遠的兩個節點:Uk和Vk,其距離定義為d(Uk,Vk),那么節點Uk或Vk即為子樹K到根節點Rk距離最長的節點。不失一般性,我們設Uk為子樹K中道根節點Rk距離最長的節點其到根節點的距離定義為d(Uk,R)。取d(Ui,R)(1<=i<=k)中最大的兩個值max1和max2,那么經過根節點R的最長路徑為max1+max2+2,所以樹R中相距最遠的兩個點的距離為:max{d(U1,V1),…, d(Uk,Vk),max1+max2+2}。

3.代碼實現

編程之美給出的代碼如下:

//數據結構定義
struct NODE
{
       NODE* pLeft;       //左孩子
       NODE* pRight;      //右孩子
       int nMaxLeft;      //左孩子中的最長距離
       int nMaxRight;     //右孩子中的最長距離
       char chValue;      //該節點的值
};

 

int nMaxLen=0;

//尋找樹中最長的兩段距離
void FindMaxLen(NODE* pRoot)
{
      //遍歷到葉子節點,返回
      if(pRoot==NULL)
      {
              return;
      }

      //如果左子樹為空,那么該節點的左邊最長距離為0
      if(pRoot->pLeft==NULL)
      {
             pRoot->nMaxLeft=0;
      }

      //如果右子樹為空,那么該節點的右邊最長距離為0
      if(pRoot->pRight==NULL)
      {
             pRoot->nMaxRight=0;
      }
 
      //如果左子樹不為空,遞歸尋找左子樹最長距離
      if(pRoot->pLeft!=NULL)
      {
             FindMaxLen(pRoot->pLeft);
      }

      //如果右子樹不為空,遞歸尋找右子樹最長距離
      if(pRoot->pRight!=NULL)
      {
             FindMaxLen(pRoot->pRight);
      }

 
      if(pRoot->pLeft!=NULL)
      {
             int nTempMax=0;
             if(pRoot->pLeft->nMaxLeft > pRoot->pLeft->nMaxRight)
             {
                     nTempMax=pRoot->pLeft->nMaxLeft;       
             }
             else
             {
                     nTempMax=pRoot->pLeft->nMaxRight;
             }
             pRoot->nMaxLeft=nTempMax+1;
      }

      //計算右子樹最長節點距離
      if(pRoot->pRight!=NULL)
      {
              int nTempMax=0;
              if(pRoot->pRight->nMaxLeft > pRoot->pRight->nMaxRight)
              {
                         nTempMax= pRoot->pRight->nMaxLeft;
              }
              else
              {
                         nTempMax= pRoot->pRight-> nMaxRight;
              }
              pRoot->nMaxRight=nTempMax+1;
       }

     //更新最長距離
     if(pRoot->nMaxLeft+pRoot->nMaxRight > nMaxLen)
     {
               nMaxLen=pRoot->nMaxLeft+pRoot->nMaxRight;
     } 
}


依據二叉樹尋找最大深度的常規思想,又有代碼如下:

struct BTNode
{
       int data;
       BTNode* pLeft;
       BTNode* pRight;
};


int maxDis = -1;

int findMaxDis(BTNode* pRoot)
{
    
     if(pRoot == NULL)
            return 0;
     
     int maxLeft  = findMaxDis(pRoot->pLeft) ;
     int maxRight = findMaxDis(pRoot->pRight);
     
     if(maxLeft + maxRight > maxDis)
     {
            maxDis = maxLeft + maxRight;
     } 
     
     return maxLeft > maxRight ? maxLeft+1 : maxRight+1;
} 

 

后一段代碼為自寫 沒有驗證其正確性。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM