已知前序和中序遍历恢复二叉树

 

[cpp]  view plain copy
  1. #include<iostream>  
  2. using namespace std;  
  3. #define TREELEN  6  
  4. //数据结构定义  
  5. struct NODE  
  6. {  
  7.     NODE* pLeft;         //左子树  
  8.     NODE* pRight;        //右子树  
  9.     char chValue;        //该节点的值  
  10. };  
  11.   
  12. void ReBuild(char* pPreOrder,char* pInOrder,int nTreeLen,NODE** pRoot)  
  13. {  
  14.     //检查边界条件  
  15.     if(pPreOrder==NULL || pInOrder==NULL)  
  16.     {  
  17.         return;  
  18.     }  
  19.   
  20.     //获得前序遍历的第一个节点  
  21.     NODE* pTemp = new NODE;  
  22.     pTemp->chValue = *pPreOrder;  
  23.     pTemp->pLeft   = NULL;  
  24.     pTemp->pRight  = NULL;  
  25.   
  26.     //如果节点为空,把当前节点复制到根节点  
  27.     if(*pRoot == NULL)  
  28.     {  
  29.         *pRoot = pTemp;  
  30.     }  
  31.   
  32.     //如果当前树长度为1,那么已经是最后一个节点  
  33.     if(nTreeLen == 1)  
  34.     {  
  35.         return;  
  36.     }  
  37.   
  38.     //寻找子树长度  
  39.     char* pOrgInOrder = pInOrder;  
  40.     char* pLeftEnd = pInOrder;  
  41.     int nTempLen = 0;  
  42.   
  43.     //找到左子树的结尾  
  44.     while(*pPreOrder != *pLeftEnd)  
  45.     {  
  46.         if(pPreOrder==NULL || pLeftEnd==NULL)  
  47.         {  
  48.             return;  
  49.         }  
  50.         nTempLen++;  
  51.         //记录临时长度,以免溢出  
  52.         if(nTempLen > nTreeLen)  
  53.         {  
  54.             break;  
  55.         }  
  56.         pLeftEnd++;  
  57.     }  
  58.   
  59.     //寻找左子树长度  
  60.     int nLeftLen = 0;  
  61.     nLeftLen = (int)(pLeftEnd-pOrgInOrder);  
  62.   
  63.     //寻找右子树长度  
  64.     int nRightLen = 0;  
  65.     nRightLen = nTreeLen - nLeftLen - 1;  
  66.   
  67.     //重建左子树  
  68.     if(nLeftLen > 0)  
  69.     {  
  70.         ReBuild(pPreOrder+1,pInOrder,nLeftLen,&((*pRoot)->pLeft));  
  71.     }  
  72.   
  73.     //重建右子树  
  74.     if(nRightLen > 0)  
  75.     {  
  76.         ReBuild(pPreOrder+nLeftLen+1,pInOrder+nLeftLen+1,nRightLen,&((*pRoot)->pRight));  
  77.     }  
  78.   
  79. }  
  80.   
  81. //前序遍历结果  
  82. void PrePrint(NODE* pRoot)  
  83. {  
  84.     if(pRoot == NULL)  
  85.     {  
  86.         return;  
  87.     }  
  88.     cout<<pRoot->chValue<<" ";  
  89.     PrePrint(pRoot->pLeft);  
  90.     PrePrint(pRoot->pRight);  
  91. }  
  92.   
  93. //中序遍历结果  
  94. void InPrint(NODE* pRoot)  
  95. {  
  96.     if(pRoot == NULL)  
  97.     {  
  98.         return;  
  99.     }  
  100.     InPrint(pRoot->pLeft);  
  101.     cout<<pRoot->chValue<<" ";  
  102.     InPrint(pRoot->pRight);  
  103. }  
  104.   
  105. void main()  
  106. {  
  107.     char szPreOrder[TREELEN] = {'a','b','d','c','e','f'};  
  108.     char szInOrder[TREELEN]  = {'d','b','a','e','c','f'};  
  109.     NODE* pRoot = NULL;  
  110.     ReBuild(szPreOrder,szInOrder,TREELEN,&pRoot);  
  111.     PrePrint(pRoot);  
  112.     cout<<endl<<endl;;  
  113.   
  114.     InPrint(pRoot);  
  115.     cout<<endl;  
  116. }  
  117.   
  118. /* 
  119. a b d c e f 
  120.  
  121. d b a e c f 
  122. */  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值