二叉树篇3

前面两篇说明了二叉树的遍历、递归、搜素与回溯的算法设计思路。这一篇要说明另一个问题:二叉树的前序、中序、后序遍历序列有什么用?能根据这些序列还原出二叉树吗?以及树的合并等等一些例子。

首先,要还原一颗二叉树至少需要中序/前序序列,这两个序列组合起来使用才能够确定根结点,左右子树的位置。特点: 前序序列中排在第一位的是根结点,而在中序序列中根结点在中间,两侧是左右子树的结点集。

用一个例子来说明: 给定一个二叉树的前序和中序序列,请重建二叉树。注意: 序列中无重复数据。

根据上面的特点,可以用递归的方法。

//函数返回值为根结点,用4个指针变量来记录子树位置
TreeNode* TreeRebuild(vector<int> pre, vector<int> In, int prestart, int preend, int Instart, int Inend){
//当传入的子树为空,返回NULL
if(prestart>premid){return NULL;}

//构造这一层的根结点
root=new TreeNode(pre[prestart]);
int p=Instart;
while(In[p]!=pre[prestart]){p++;}//找到这一层的根结点在In序列中的位置

//终止条件准许NULL结点传入,因此这里不用再限制了
root->left=TreeRebuild(pre,In,prestart+1,prestart+p-Instart,Instart,p);

root->right=TreeRebuild(pre,In,prestart+p-Instart+1,preend,p+1,Inend);
//处理完这一层的子树后,返回这个root
return root;

}

这个例子是根据前序、中序遍历还原二叉树的经典例子。使用的是递归的方法。

再看另一个例子:给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:

  • 二叉树的根是数组中的最大元素。

  • 左子树是通过数组中最大值左边部分构造出的最大二叉树。

  • 右子树是通过数组中最大值右边部分构造出的最大二叉树。

通过给定的数组构建最大二叉树,并且输出这个树的根节点。

与上面的写法类似:

TreeNode* TreeRebuild(vector<int> nums, int start, int end){
//终止条件
if(start>end) return NULL;
//从start->end查找最大值
int index=start,max=nums[start],maxindex=start;
while(index<=end){if(max<nums[index]){max=nums[index];maxindex=index;}++index;}
root=new TreeNode(max);

root->left=TreeRebuild(nums, start, maxindex-1);
root->right=TreeRebuild(nums, maxindex+1,end);
return root;

}

注意:在上面的重构函数中都通过使用下标参数来缩减控制nums中的子树区间(为了避免重复的构造子区间。),这是一种可以减少空间消耗的方法。

二叉树算法的相关的内容中应当还有一块二叉搜索树的拼图,然而在这里先不补充了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值