剑指offer--面试题6 重建二叉树
2016-03-30 15:12
691 查看
根据先序遍历和中序遍历还原二叉树
1.二叉树先序遍历的第一个结点必定是根节点,所以可以在中序遍历中确定根节点的位置。
2.中序遍历中,根节点之前的结点都是二叉树的左子树,之后的都是二叉树的右子树。可以得到左子树的结点个数m和右子树的结点个数n。
3.同时,先序遍历中,根节点之后的m个结点都是二叉树的左子树。
4.这是重复上面3个步骤,构建左右子树,用递归方法完成。
1.二叉树先序遍历的第一个结点必定是根节点,所以可以在中序遍历中确定根节点的位置。
2.中序遍历中,根节点之前的结点都是二叉树的左子树,之后的都是二叉树的右子树。可以得到左子树的结点个数m和右子树的结点个数n。
3.同时,先序遍历中,根节点之后的m个结点都是二叉树的左子树。
4.这是重复上面3个步骤,构建左右子树,用递归方法完成。
#include <iostream> #include <cstring> #include <cstdlib> #include <algorithm> #include <cstdio> using namespace std; struct BinaryTreeNode { int value; BinaryTreeNode *left; BinaryTreeNode *right; }; //递归寻找结点 BinaryTreeNode * BuildRecursivly(int *preStart,int *preEnd,int *inStart,int *inEnd) { //在先序遍历序列中取出第一个元素即为根节点元素 int value = preStart[0]; //printf("value:%d,preStart:%d,preEnd:%d,inStart:%d,inEnd:%d\n",value,*preStart,*preEnd,*inStart,*inEnd); //构造根节点 BinaryTreeNode *root = new BinaryTreeNode(); root->value=value; root->left=NULL; root->right=NULL; //递归结束的情况,即只剩一个叶子节点 if(preStart == preEnd) { if(inStart == inEnd && (*preStart == *inStart)) { //printf("node:%d,left:%d,right:%d\n",root->value,root->left,root->right); return root; } else { throw exception(); } } //在中序遍历序列中找出根节点的位置 int *inorder=inStart; while(inorder <= inEnd && *inorder != value) { inorder++; } if(inorder == inEnd && *inorder != value) { throw exception(); } //取得左子树的长度以及在先序遍历中取得右子树的起始位置 int leftTreeLen = inorder - inStart; int *preLeftEnd = preStart + leftTreeLen; //如果左子树存在,则递归左子树 if(leftTreeLen > 0) root->left=BuildRecursivly(preStart+1,preLeftEnd,inStart,inorder-1); //如果右子树存在,则递归右子树 if((preEnd - preStart) > leftTreeLen) root->right=BuildRecursivly(preLeftEnd+1,preEnd,inorder+1,inEnd); return root; } //创建二叉树 BinaryTreeNode *BulidBinaryTree(int *szPrevOrder, int *szInOrder, int length) { if(szPrevOrder==NULL||szInOrder==NULL) return NULL; return BuildRecursivly(szPrevOrder, szPrevOrder+length-1, szInOrder, szInOrder+length-1); } void preOrder(BinaryTreeNode *root)//先序遍历 { if(root!=NULL) { //根 printf("%d ",root->value); //左子树 preOrder(root->left); //右子树 preOrder(root->right); } } void InOrder(BinaryTreeNode *root)//中序遍历 { if(root!=NULL) { //左子树 preOrder(root->left); //根 printf("%d ",root->value); //右子树 preOrder(root->right); } } void postOder(BinaryTreeNode *root) { if(root!=NULL) { //左子树 preOrder(root->left); //右子树 preOrder(root->right); //根 printf("%d ",root->value); } } int main() { int szPrevOrder[] = {1, 2, 4, 7, 3, 5, 6, 8}; //二叉树的先序遍历 int szInOrder[] = {4, 7, 2, 1, 5, 3, 8, 6}; //二叉树的中序遍历 int length = sizeof(szPrevOrder)/sizeof(int); BinaryTreeNode *root = BulidBinaryTree(szPrevOrder,szInOrder,length); cout<<"PrevOrder: "; preOrder(root); cout<<endl<<"InOrder: "; InOrder(root); cout<<endl<<"PostOrder: "; postOder(root); cout<<endl; return 0; }