二叉树的重构
引言:本篇博客想和大家讨论一下有关二叉树的遍历问题,小编在最近学习二叉树时总被递归遍历绕晕,希望这篇“血泪”酿成的心得能帮助到大家
结点结构和所用到的函数声明
#define TYPE int
typedef struct TreeNode //二叉树结点结构
{
TYPE data; //二叉树存储内容
struct TreeNode* left; //二叉树的左指针 → 指向左孩子
struct TreeNode* right; //二叉树的右指针 → 指向右孩子
}TreeNode;
TreeNode* create_node(TYPE data); //创建一个二叉树结点,形参为结点的内容
本篇博客的题目来自牛客网→题库→在线编程→ 剑指offer
问题1:现在有一个树的前序遍历和中序遍历,重新构建二叉树
解题思路:
①
我们均以该树讲解
前序遍历结果:(4,2,1,3,5)
中序遍历结果:(1,2,3,4,5)
3种遍历的访问顺序:前序遍历→根左右 、 中序遍历→左根右 、 后序遍历→左右根
②
判断1:前序遍历中排头结点是一颗树的根结点,对其子树同样适用
证明1:上述树中,4为整颗树的根结点,2为左子树的根结点,5为右子树的根结点,以此类推
判断2:中序遍历中在根结点左边的为其左子树结点,根结点右边的为其右子树结点,对这颗树的子树同样适用
证明2:上述树中,(1,2,3)是根结点4的左子树,(5)是根结点4的右子树,以此类推
③
通过上述判断,我们可以将一颗二叉树通过前序遍历确定根结点,中序遍历确定该根结点的左右孩子,再从左右子树中找其根结点与其对应的左右孩子……
讲到这我们可以自然而然的想到使用递归解题,下附代码
实现代码:
TreeNode* reconstruct_tree(TYPE* pre, TYPE* in, size_t size)
//pre为前序序列数组,in为中序序列数组,size为数组的大小
//默认调用者输入大小相等的两个数组
{
if(0 >= size) return NULL;
TreeNode* root = create_node(pre[0]);
int len = 0;
for(; len<size; ++len)
{
if(in[len] == pre[0]) break;
}
//此时将数组下标作为长度是因为此时并不包括这个root结点
root->left = reconstruct_tree(pre+1,in,len);
root->right = reconstruct_tree(pre+1+len,in+len+1,size-1-len);
return root;
}
问题2:判断一个序列是否是有序二叉树的后序遍历结果(bool 类型)
解题思路:
有序二叉树:结点的左孩子内容小于父结点内容,右孩子内容大于父结点内容
①
当理解了问题1的思路后 ,我们首先想到的就是后续遍历 → 左右根
后序遍历结果:(1,3,2,5,4)
②
判断1:后续遍历将一颗树的顺序分成左子树,右子树,根
证明1:(1,3,2)为根结点4的左子树成员,(5)为根结点4的右子树成员,对其子树也适用
判断2:在有序二叉树中,左子树的成员内容均小于其根结点内容,右子树则反之
证明2:(1,3,2)均小于4,(5)大于4,对其子树也适用
③
通过上述分析,我们的目标便成了将一个后续序列逐级分成三个部分(左,右,根)
实现代码:
bool helper_BST(TYPE* arr, int head, int tail)
//head为数组的头,tail为数组的尾,通过修改改值来得到对应子树的序列
{
if(head >= tail)
return true;
int pivot = head;
while(arr[pivot] < arr[tail])
pivot++;
for(int j = pivot;j<tail;++j) //防止在右子树中有值小于根结点的值
if(arr[j]<arr[tail])
return false;
bool flag = helper_BST(arr,head,pivot-1);
//左子树不满足要求则无需对右子树进行判断
if(flag) flag = helper_BST(arr,pivot,tail-1);
return flag;
}
bool VerifySquenceOfBST(TYPE* sequence, int size)
{
if(0 >= size) return false;
return helper_BST(sequence,0,size-1);
}
总结
本文主要简单介绍了小编对二叉树前序、中序、后续遍历的看法,在代码的精简性上仍有不足,望大佬们海涵,若有表述不当,可优化代码部分请及时指出。小编衷心希望能对初学二叉树的大家带来一点解题的灵感。