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

来源:互联网 发布:大禹装饰软件官方网站 编辑:程序博客网 时间:2024/06/06 03:42

题目:

输入某二叉树的前序遍历和中序遍历,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含有重复的数字。

例如,前序遍历序列:{1,2,4,7,3,5,6,8},中序遍历序列:{4,7,2,1,5,3,8,6}

则重建出的二叉树如下所示,并输出它的头结点1。



基本思想:

前序遍历:

前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树。

中序遍历:

中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。在遍历左、右子树时,仍然先遍历左子树,再访问根结点,最后遍历右子树。

1、先序遍历序列的第一个元素必定是根节点,可以由此获取二叉树的根节点。

2、根据根节点,在中序遍历序列中查找该节点,由中序遍历的性质可知,中序遍历中该根节点左边的序列必定在根节点的左子树中,而根节点右边的序列必定在右子树中。由此可以知道先序遍历中左子树以及右子树的起止位置。

3、分别对左子树和右子树重复上述的过程,直至所有的子树的起止位置相等时,说明已经到达叶子节点,遍历完毕。


    #include <iostream>      #include <deque>      using namespace std;            //二叉树结点定义      typedef struct BiTreeNode{          int data;          //左右孩子指针          struct BiTreeNode *lchild;          struct BiTreeNode *rchild;      }BiTreeNode,*BiTree;              //访问函数      void Visit(BiTree T)      {          if(T->data != -1)              cout<<T->data<<" ";      }            //先序遍历      void PreOrder(BiTree T)      {          if(T != NULL)          {              //访问根节点              Visit(T);              //访问左子结点              PreOrder(T->lchild);              //访问右子结点              PreOrder(T->rchild);          }      }  //中序遍历void InOrder(BiTree T){if(T != NULL){//访问左子结点InOrder(T->lchild);//访问根节点Visit(T);//访问右子结点InOrder(T->rchild);}}//后序遍历void PostOrder(BiTree T){if(T != NULL){//访问左子结点PostOrder(T->lchild);//访问右子结点PostOrder(T->rchild);//访问根节点Visit(T);}}BiTree constructor(int * startP,int * endP,int * startI,int * endI){//前序遍历序列的第一个数字是根节点的值int rootValue=startP[0];BiTree root;root = (BiTree)malloc(sizeof(BiTreeNode)); root->data=rootValue;root->lchild=root->rchild=NULL;if(startP==endP){if(startI==endI && *startP==*startI)return root;elsereturn NULL;}//在中序遍历中找到根节点的值int * rootI=startI;while(rootI<=endI && *rootI!=rootValue)++rootI;if(rootI==endI && *rootI!=rootValue)return NULL;int leftlen=rootI-startI;int *leftPE=startP+leftlen;if(leftlen>0){//构建左子树root->lchild=constructor(startP+1,leftPE,startI,rootI-1);}if(leftlen<endP-startP){//构建右子树root->rchild=constructor(leftPE+1,endP,rootI+1,endI);}return root;}BiTree foo(int * pre,int * ino,int len){if(pre==NULL || ino==NULL ||len<=0)return NULL;return constructor(pre,pre+len-1,ino,ino+len-1);}          void main()      {  int pre[]={1,2,4,7,3,5,6,8};int ino[]={4,7,2,1,5,3,8,6};int len=sizeof(pre)/sizeof(pre[0]);BiTree T = foo(pre,ino,len);cout<<"二叉树根节点:";cout<<T->data<<endl;                cout<<"先序遍历:";          PreOrder(T);          cout<<endl;          cout<<"中序遍历:";          InOrder(T);          cout<<endl;  cout<<"后序遍历:";          PostOrder(T);          cout<<endl;     }  


0 0
原创粉丝点击