您的位置:首页 > 职场人生

剑指offer--面试题6 重建二叉树

2016-03-30 15:12 691 查看
根据先序遍历和中序遍历还原二叉树

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: