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

来源:互联网 发布:mac怎么关闭访客模式 编辑:程序博客网 时间:2024/06/15 18:32

根据先序遍历和中序遍历还原二叉树


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;}

0 0
原创粉丝点击