面试100题:11.求二叉树中节点的最大距离

本文提供两种求解二叉树中相距最远的两个节点间距离的方法。通过计算最深的左子树和右子树的距离之和来得出最大距离。包括详细的代码实现及运行示例。

题目

写一个程序,求一棵二叉树中相距最远的两个节点之间的距离。如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义"距离"为两节点之间边的个数。

分析:把最深的左子树距离加上最深的右子树距离就是二叉树中两个节点的最大距离。

解一:GetMaxPathFromBST

  1. /*Title:    11.求二叉树中节点的最大距离: 解一 
  2. Author:     gocode 
  3. Date:       2012-10-15*/  
  4.   
  5. #include <assert.h>  
  6. #include <iostream>  
  7. using namespace std;  
  8.   
  9. // 二叉树结点  
  10. typedef struct tagBSTNode  
  11. {  
  12.     int nValue;  
  13.     tagBSTNode *psLeft;  
  14.     tagBSTNode *psRight;  
  15.   
  16.     // 二叉树结构的构造函数,用于初始化  
  17.     tagBSTNode()  
  18.     {  
  19.         nValue = 0;  
  20.         psLeft = psRight = NULL;  
  21.     }  
  22. } S_BSTNode;  
  23.   
  24. // 删除结点清除内存  
  25. void DeleteAllNode(S_BSTNode* pRoot)  
  26. {  
  27.     if(NULL == pRoot) return;  
  28.   
  29.     DeleteAllNode(pRoot->psLeft);  
  30.     DeleteAllNode(pRoot->psRight);  
  31.   
  32.     delete pRoot;  
  33. }  
  34.   
  35. // 创建二叉树  
  36. void AddBSTreeNode(S_BSTNode* &pRoot, int nValue)  
  37. {  
  38.     if(NULL == pRoot)  
  39.     {  
  40.         pRoot = new S_BSTNode;  
  41.         assert(NULL != pRoot);  
  42.         pRoot->nValue = nValue;  
  43.         return;  
  44.     }  
  45.   
  46.     if(pRoot->nValue > nValue)  
  47.     {  
  48.         AddBSTreeNode(pRoot->psLeft, nValue);  
  49.     }  
  50.     else if( pRoot->nValue < nValue)  
  51.     {  
  52.         AddBSTreeNode(pRoot->psRight, nValue);  
  53.     }  
  54. }  
  55.   
  56. // 取得最大深度  
  57. int GetMaxDepth(const S_BSTNode* pRoot)  
  58. {  
  59.     // 根节点为空,则返回0  
  60.     if(NULL == pRoot)  
  61.         return 0;  
  62.   
  63.     // 左右结点都为空,则返回0  
  64.     // 如有一个孩子,则继续计算深度  
  65.     if(NULL == pRoot->psLeft && NULL == pRoot->psRight)  
  66.         return 0;  
  67.   
  68.     int nLeftDepth = 0, nRightDepth = 0;  
  69.     if(NULL != pRoot->psLeft)  
  70.         nLeftDepth = GetMaxDepth(pRoot->psLeft) + 1;  
  71.   
  72.     if(NULL != pRoot->psRight)  
  73.         nRightDepth = GetMaxDepth(pRoot->psRight) + 1;  
  74.   
  75.     // 比较左右子树的深度,返回最大值  
  76.     if(nRightDepth >= nLeftDepth)  
  77.         return nRightDepth;  
  78.     else  
  79.         return nLeftDepth;  
  80. }  
  81.   
  82. // 取得最大距离=左最大深度+右最大深度  
  83. int GetMaxDistance(const S_BSTNode* pRoot)  
  84. {  
  85.     if(NULL == pRoot) return 0;  
  86.   
  87.     int nLeftDepth = GetMaxDepth(pRoot->psLeft);  
  88.     nLeftDepth += ((pRoot->psLeft != NULL) ? 1 : 0);  
  89.   
  90.     int nRightDepth =GetMaxDepth(pRoot->psRight);  
  91.     nRightDepth += ((pRoot->psRight != NULL) ? 1 : 0);  
  92.   
  93.     return nLeftDepth + nRightDepth;  
  94. }  
  95.   
  96. int main()  
  97. {  
  98.     S_BSTNode *pRoot = NULL;  
  99.     AddBSTreeNode(pRoot, 5);  
  100.     AddBSTreeNode(pRoot, 4);  
  101.     AddBSTreeNode(pRoot, 8);  
  102.     AddBSTreeNode(pRoot, 7);  
  103.     AddBSTreeNode(pRoot, 12);  
  104.     AddBSTreeNode(pRoot, 10);  
  105.   
  106.     int nMaxDis = GetMaxDistance(pRoot);  
  107.     cout <<"11.求二叉树中节点的最大距离:解一"<<endl;  
  108.     cout << "Max distance of Binary Search Tree is " << nMaxDis << endl;  
  109.     DeleteAllNode(pRoot);  
  110.     system("pause");  
  111.     return 0;  
  112. }  

解二:GetMaxPathFromBST2

  1. /*Title:    11.求二叉树中节点的最大距离: 解二 
  2. Author:     gocode 
  3. Date:       2012-10-15*/  
  4.    
  5. #include <assert.h>  
  6. #include <iostream>  
  7. #include<tchar.h>  
  8. using namespace std;  
  9.    
  10. // 数据结构定义  
  11. typedef struct NODE  
  12. {  
  13.     NODE* psLeft;// 左子树  
  14.     NODE* psRight;// 右子树  
  15.     int nMaxLeft;// 左子树中的最长距离  
  16.     int nMaxRight; // 右子树中的最长距离  
  17.     int nValue;// 该节点的值  
  18.    
  19.     NODE()  
  20.     {  
  21.         nValue = nMaxLeft = nMaxRight = 0;  
  22.         psLeft = psRight = NULL;  
  23.     }  
  24.    
  25. } S_BSTNode;  
  26.    
  27. void AddBSTreeNode(S_BSTNode* &pRoot, int nValue)  
  28. {  
  29.     if (NULL == pRoot)  
  30.     {  
  31.         pRoot = new S_BSTNode;  
  32.         assert(NULL != pRoot);  
  33.         pRoot->nValue = nValue;  
  34.         return;  
  35.     }  
  36.    
  37.     if (pRoot->nValue > nValue)  
  38.         AddBSTreeNode(pRoot->psLeft, nValue);  
  39.     else if ( pRoot->nValue < nValue)  
  40.         AddBSTreeNode(pRoot->psRight, nValue);  
  41. }  
  42.    
  43. void DeleteAllNode(S_BSTNode* pRoot)  
  44. {  
  45.     if (NULL == pRoot)return;  
  46.    
  47.     DeleteAllNode(pRoot->psLeft);  
  48.     DeleteAllNode(pRoot->psRight);  
  49.    
  50.     delete pRoot;  
  51. }  
  52.    
  53. int g_nMaxLen = 0;  
  54.    
  55. // 寻找树中最长的两段距离  
  56. void FindMaxLen(NODE* pRoot)  
  57. {  
  58.     // 遍历到叶子节点,返回  
  59.     if(NULL == pRoot)  
  60.         return;  
  61.    
  62.     // 如果左子树为空,那么该节点的左边最长距离为0  
  63.     if(NULL == pRoot->psLeft)  
  64.         pRoot->nMaxLeft = 0;  
  65.    
  66.     // 如果右子树为空,那么该节点的右边最长距离为0  
  67.     if(NULL == pRoot->psRight)  
  68.         pRoot->nMaxRight = 0;  
  69.    
  70.     // 如果左子树不为空,递归寻找左子树最长距离  
  71.     if(pRoot->psLeft != NULL)  
  72.         FindMaxLen(pRoot->psLeft);  
  73.    
  74.     // 如果右子树不为空,递归寻找右子树最长距离  
  75.     if(pRoot->psRight != NULL)  
  76.         FindMaxLen(pRoot->psRight);  
  77.    
  78.     // 计算左子树最长节点距离  
  79.     if(pRoot->psLeft != NULL)  
  80.     {  
  81.         int nTempMax = 0;  
  82.         if(pRoot->psLeft->nMaxLeft > pRoot->psLeft->nMaxRight)  
  83.             nTempMax = pRoot->psLeft->nMaxLeft;  
  84.         else  
  85.             nTempMax = pRoot->psLeft->nMaxRight;  
  86.    
  87.         pRoot->nMaxLeft = nTempMax + 1;  
  88.     }  
  89.    
  90.     // 计算右子树最长节点距离  
  91.     if(pRoot->psRight != NULL)  
  92.     {  
  93.         int nTempMax = 0;  
  94.         if(pRoot->psRight->nMaxLeft > pRoot->psRight->nMaxRight)  
  95.             nTempMax = pRoot->psRight->nMaxLeft;  
  96.         else  
  97.             nTempMax = pRoot->psRight->nMaxRight;  
  98.    
  99.         pRoot->nMaxRight = nTempMax + 1;  
  100.     }  
  101.    
  102.     // 更新最长距离  
  103.     if((pRoot->nMaxLeft + pRoot->nMaxRight) > g_nMaxLen)  
  104.         g_nMaxLen = pRoot->nMaxLeft + pRoot->nMaxRight;  
  105. }  
  106.    
  107. int _tmain(int argc, _TCHAR* argv[])  
  108. {  
  109.     S_BSTNode *pRoot = NULL;  
  110.     AddBSTreeNode(pRoot, 5);  
  111.     AddBSTreeNode(pRoot, 4);  
  112.     AddBSTreeNode(pRoot, 8);  
  113.     AddBSTreeNode(pRoot, 7);  
  114.     AddBSTreeNode(pRoot, 12);  
  115.     AddBSTreeNode(pRoot, 10);  
  116.    
  117.     FindMaxLen(pRoot);  
  118.     cout <<"11.求二叉树中节点的最大距离:解二"<<endl;  
  119.     cout << "Max distance of Binary Search Tree is " << g_nMaxLen << endl;  
  120.     DeleteAllNode(pRoot);  
  121.     system("pause");  
  122.     return 0;  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值