C++编程之美-结构之法(代码清单3-12)

本文介绍了一种使用前序遍历和中序遍历结果重建二叉树的方法。通过分析遍历序列,算法能够确定树的结构,并创建相应的二叉树节点。示例代码展示了如何实现这一过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码清单3-12

// ReBuild.cpp : 根据前序及中序结果,重建树的根节点
//

// 定义树的长度。为了后序调用实现的简单,我们直接用宏定义了树节点的总数
#define TREELEN 6

// 树节点
struct NODE
{
     NODE* pLeft;         // 左节点
     NODE* pRight;        // 右节点
     char chValue;        // 节点值
};

void ReBuild(char* pPreOrder,       	// 前序遍历结果
                char* pInOrder,        	// 中序遍历结果
                int nTreeLen,       	// 树长度
                NODE** pRoot)         	// 根节点
{

     // 检查边界条件 
     if(pPreOrder == NULL || pInOrder == NULL)
     {
          return;
     }

     // 获得前序遍历的第一个节点
     NODE* pTemp = new NODE;
     pTemp -> chValue = *pPreOrder;
     pTemp -> pLeft = NULL;
     pTemp -> pRight = NULL;

     // 如果节点为空,把当前节点复制到根节点
     if(*pRoot == NULL)
     {
          *pRoot = pTemp;
     }

     // 如果当前树长度为1,那么已经是最后一个节点
     if(nTreeLen == 1)
     {
          return;
     }

     // 寻找子树长度 
     char* pOrgInOrder = pInOrder;
     char* pLeftEnd = pInOrder; 
     int nTempLen = 0;

     // 找到左子树的结尾
     while(*pPreOrder != *pLeftEnd)
     {
          if(pPreOrder == NULL || pLeftEnd == NULL)
          {
               return;
          }

         nTempLen++;

         // 记录临时长度,以免溢出
         if(nTempLen > nTreeLen)
         {
               break;
          }

          pLeftEnd++;
     }

     // 寻找左子树长度
     int nLeftLen = 0;
     nLeftLen = (int)(pLeftEnd - pOrgInOrder);

     // 寻找右子树长度
     int nRightLen = 0;
     nRightLen = nTreeLen – nLeftLen - 1;

     // 重建左子树
     if(nLeftLen > 0)
     {
          ReBuild(pPreOrder + 1, pInOrder, nLeftLen, &((*pRoot) -> pLeft));
     }

     // 重建右子树
     if(nRightLen > 0)
     {
          ReBuild(pPreOrder + nLeftLen + 1, pInOrder + nLeftLen + 1,  
            nRightLen, &((*pRoot) -> pRight)); 
     }

}

// 示例的调用代码
int main(int argc, char* argv[])
{
     char szPreOrder[TREELEN]={'a', 'b', 'd', 'c', 'e', 'f'};
     char szInOrder[TREELEN]={'d', 'b', 'a', 'e', 'c', 'f'};

     NODE* pRoot = NULL;
     ReBuild(szPreOrder, szInOrder, TREELEN, &pRoot); 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值