据前序遍历和中序遍历重建二叉树
2016-11-24 18:08
309 查看
这是一道面试题
由前序遍历和中序遍历重建二叉树(前序序列:1 2 3 4 5 6 - 中序序列:3 2 4 1 6 5)数据不含重复值
这个可以分析一下
前序遍历序列1 2 3 4 5 6,前序遍历规则是根--左--右
中序遍历序列3 2 4 1 6 5,中序遍历规则是左--根--右
由前序遍历可知根节点为第一个元素1,在中序遍历序列中找到1对应位置,
则1的左边就是左子树324,右边就是右子树56;
在找到前序遍历序列中从第二个位置开始往后找相同数目的节点为左子树234,剩余的就是右子树序列65,
再根据前序遍历规则可知,左子树序列里第一个就是左子树的根节点2,右子树序列里的第一个就是有右子树的根节点5,
再根据中序遍历序列可知,左子树的根节点2左边的一定是以其为根节点的左子树序列3,右边就是以其为根节点的右子树序列4,
右子树的根节点5左边的一定是以其为根节点的右子树序列6,直至序列为空,就可以完整重建二叉树了
如图:
代码
代码实现:
定义节点:
函数实现
后序遍历
测试代码
测试结果:
由前序遍历和中序遍历重建二叉树(前序序列:1 2 3 4 5 6 - 中序序列:3 2 4 1 6 5)数据不含重复值
这个可以分析一下
前序遍历序列1 2 3 4 5 6,前序遍历规则是根--左--右
中序遍历序列3 2 4 1 6 5,中序遍历规则是左--根--右
由前序遍历可知根节点为第一个元素1,在中序遍历序列中找到1对应位置,
则1的左边就是左子树324,右边就是右子树56;
在找到前序遍历序列中从第二个位置开始往后找相同数目的节点为左子树234,剩余的就是右子树序列65,
再根据前序遍历规则可知,左子树序列里第一个就是左子树的根节点2,右子树序列里的第一个就是有右子树的根节点5,
再根据中序遍历序列可知,左子树的根节点2左边的一定是以其为根节点的左子树序列3,右边就是以其为根节点的右子树序列4,
右子树的根节点5左边的一定是以其为根节点的右子树序列6,直至序列为空,就可以完整重建二叉树了
如图:
代码
代码实现:
定义节点:
#include<iostream> #include<stdlib.h> using namespace std; //定义一棵二叉树的节点 struct BTreeNode { int value; BTreeNode * left; BTreeNode* right; };
函数实现
BTreeNode * RebuildTree(int* PreOrder,int* InOrder,int length) { //判断输入值是否合法 if(PreOrder == NULL || InOrder == NULL || length<=0) { return NULL; } else { return RebuildCore(PreOrder,PreOrder+length-1,InOrder,InOrder+length-1); } } BTreeNode *RebuildCore(int *startPreOrder,int *endPreOrder,int *startInOrder,int *endInOrder) { //2.找到前序遍历中的根节点并创建一个节点保存节点值 BTreeNode *root = new BTreeNode(); root->value = startPreOrder[0]; root->left = NULL; root->right = NULL; //3.判断是否找完了此次中序遍历,若是找完了,则返回 root if(startInOrder == endInOrder && *startInOrder == *endInOrder) { return root; } //4.根据此根节点的值在中序遍历中找此次节点的位置 int * rootIn = startInOrder; while(*startPreOrder != *rootIn) { rootIn++; } //6.根据此根节点在中序遍历中的位置,递归还原左子树 int leftlength = rootIn-startInOrder; if(leftlength>0) { root->left = RebuildCore(startPreOrder+1,startPreOrder+leftlength,startInOrder,startInOrder+leftlength-1); } //此处千万不要错写成 else if 因为若是这样,判断满足上面的递归条件,则进入递归还原左子树,当左子树完全被还原后,再调回这个点的时候,就不会继续执行 else if 语句了,因为上面的条件已经满足,所以右子树将没办法还原了 if(leftlength+startInOrder < endInOrder)//左子树长度加上中序的起始位置后若仍然小于整个中序长度则说明该节点还存在右子树,所以继续递归还原右子树 {//7.根据此根节点在中序遍历中的位置,递归还原右子树 root->right = RebuildCore(startPreOrder+leftlength+1,endPreOrder,startInOrder+leftlength+1,endInOrder); } return root; }
后序遍历
void PostOrder(BTreeNode *root) { if(root->left != NULL) { PostOrder(root->left); } if(root->right != NULL) { PostOrder(root->right); } if(root != NULL) { cout<<root->value<<" "; } }
测试代码
int main() { int preorder[] = {1,2,3,4,5,6}; int inorder[] = {3,2,4,1,6,5}; BTreeNode *root = RebuildTree(&preorder[0],&inorder[0],6); PostOrder(root);//324651 cout<<endl; system("pause"); return 0 ; }
测试结果:
相关文章推荐
- 根据前序遍历序列和中序遍历序列重建二叉树
- 027根据前序遍历和中序遍历,重建二叉树(keep it up)
- 重建二叉树,输入某二叉树的前序遍历和中序遍历的结果,重建出二叉树,假设输入的前序和中序遍历结果中不含重复的数字
- 前序遍历和中序遍历重建二叉树
- 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
- 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。
- 根据前序遍历和中序遍历重建二叉树
- 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
- 由前序遍历和中序遍历重建二叉树
- 根据前序遍历和中序遍历重建二叉树
- 刷题之路----根据前序遍历和中序遍历或者后序遍历和中序遍历重建二叉树
- 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
- 前序遍历和中序遍历重建二叉树
- 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5
- 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,
- 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
- 输入某二叉树的前序遍历和中序遍历的结果请重建出该二叉树。
- 重建二叉树(前序遍历和中序遍历)
- 剑指offer 重建二叉树-前序遍历和中序遍历重建
- 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。