输入某二叉树的前序遍历和中序遍历的结果,重建此二叉树。

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序序列和中序序列的结果都不含重复的数字,例如输入前序序列{1,2,4,7,3,5,6,8}和中序序列{4,7,2,1,5,3,8,6},则重建树并输出它的头结点,二叉树的头结点定义如下:

struct BinaryTreeNode{

  int m_value;

  BinryTreeNode *pleft;

  BinaryTreeNode *pright;

}

   其实对于二叉树的各种遍历算法的具体实现难度远远大于理解,对我来说在上数据结构课时,就对前、中、后三种遍历思想有自认为还可以的理解(也就是说给我一棵树,我绝对可以准确的写出它的三种遍历序列,也可通过已知的前(后)序列和中序序列重新画出这棵树),但到了具体的代码实现就比较懵逼了。。。对递归这种需要在脑子中像计算机一样跑N遍的方式好难准确无误的推敲啊。。。每次遇到递归的算法就很尴尬,看的懂但是不会自己写,导致自己的动态规划算法学的很烂0.0,所以对于递归还得加强学习啊!!!

 

如果理解了递归的访问,那么建树的过程就容易多了,前序遍历序列的第一个数(后序遍历的最后一个数)一定是根结点,所以可以根据此结点在中序序列中的位置把中序序列分为左子树和右子数两个部分,同样的道理,在左子树和右子数中同样可以用到这样的规律来确定每个中间结点。

 1 #include<iostream>
 2 using namespace std;
 3 struct  BinaryTreeNode
 4 {
 5     int m_value;
 6     BinaryTreeNode *p_left;
 7     BinaryTreeNode *p_right;
 8 };
 9 BinaryTreeNode* ConstructCore(int *startPreorder, int *endPreorder, int *startInorder, int *endInorder)//前序序列的开始、结束指针和中序序列的开始结束指针
10 {
11     int rootValue = startPreorder[0];//前序序列的第一个值必然是根结点
12     BinaryTreeNode* root = new BinaryTreeNode();
13     root->m_value = rootValue;
14     root->p_left = nullptr;
15     root->p_right = nullptr;
16     if (startPreorder == endPreorder){
17         if (startInorder == endInorder&&*startPreorder == *startInorder)//只有一个数字
18             return root;
19         else
20             throw exception("Invalid input");
21     }
22     int* rootInorder = startInorder;//在中序序列中找到根节点的位置
23     while (rootInorder <= endInorder&& *rootInorder != rootValue)
24         ++rootInorder;
25     if (rootInorder == endInorder&&*rootInorder != rootValue)
26         throw exception("Invalid Input");
27     int leftLength = rootInorder - startInorder;//左子树序列长度
28     int* leftPreorderEnd = startPreorder + leftLength;//左子树前序序列的最后一个结点
29     if (leftLength > 0)//建立左子树
30     {
31         root->p_left = ConstructCore(startPreorder + 1, leftPreorderEnd, startInorder, rootInorder-1);
32     }
33     if (leftLength < endPreorder - startPreorder)//建立右子树
34     {
35         root->p_right = ConstructCore(leftPreorderEnd + 1, endPreorder, rootInorder + 1, endInorder);
36     }
37     return root;
38 }
39 BinaryTreeNode* Construt(int *preorder, int *inorder, int length)//输入前序序列,中序序列和序列长度
40 {
41     if (preorder == nullptr || inorder == nullptr || length <= 0)
42         return nullptr;
43     return ConstructCore(preorder, preorder + length - 1, inorder, inorder + length - 1);
44 }

 

转载于:https://www.cnblogs.com/General-up/p/5402362.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值