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

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章