NYOJ221二叉树重建(已知先序和中序求后序)
2013-11-23 16:11
246 查看
题意:大概意思就是给你一个二叉树的先序遍历和中序遍历,然后需要你求出后序遍历并输出到屏幕上面
思路分析: 首先明确三种遍历的特点:
先序遍历:先访问根节点,接着访问左子树,再访问右子树,由此可以明确先序遍历的第一个节点一定是根节点
中序遍历:先访问左子树,接着访问根节点,然后访问右子树,由此可以知道如果知道根节点,那么中序遍历根节点左边为左子树,右边有右子树
后序遍历:先访问左子树,接着访问右子树,最后访问根节点,由此可以知道后序遍历最后一个一定是根节点。
根据以上三种遍历的特点,我们可以分析,已知先序遍历和中序遍历的情况下,我们可以由先序遍历知道根节点,然后在中序遍历中找出根节点的位置,那么中序序列根节点左边为左子树,右边为右子树,接下来关键:我们思考一下,对于一个只有两层,左右树存在,那么根节点确定吧,那么,在我们这个给出的遍历中,抛开根节点,每一个这样的父节点我们都可以当做隔离开来的这个两层树的根节点,不知道懂了没,意思就是,我们在去掉根节点的先序中,把遍历的下一个节点(当然根节点下面的左右子树分开)当做新的根节点并在中序序列中查找位置,不断如此递归,把中序不断分开,当递归完左子树之后,同样如此递归右子树,当然,在每次这样的过程中,我们需要同时保存数据,建立二叉树。
如果有树:前序为ABDGHCEIF ,中序为:GDHBAEICF。
按照以上意思,A为第一次递归根节点,中序分为:GDHB AEICF;
第二次递归 B为在中序中查找的节点 分为:GDH
第三次递归 D为在中序中查找的节点 分为:G H
接着G,后面没了,左边递归完成,G为左子树最后一个叶子节点,然后回溯。。。。
右子树是同样的道理,注意,每次我们递归的时候在中间建立了二叉树,并且进行了赋值
代码:
思路分析: 首先明确三种遍历的特点:
先序遍历:先访问根节点,接着访问左子树,再访问右子树,由此可以明确先序遍历的第一个节点一定是根节点
中序遍历:先访问左子树,接着访问根节点,然后访问右子树,由此可以知道如果知道根节点,那么中序遍历根节点左边为左子树,右边有右子树
后序遍历:先访问左子树,接着访问右子树,最后访问根节点,由此可以知道后序遍历最后一个一定是根节点。
根据以上三种遍历的特点,我们可以分析,已知先序遍历和中序遍历的情况下,我们可以由先序遍历知道根节点,然后在中序遍历中找出根节点的位置,那么中序序列根节点左边为左子树,右边为右子树,接下来关键:我们思考一下,对于一个只有两层,左右树存在,那么根节点确定吧,那么,在我们这个给出的遍历中,抛开根节点,每一个这样的父节点我们都可以当做隔离开来的这个两层树的根节点,不知道懂了没,意思就是,我们在去掉根节点的先序中,把遍历的下一个节点(当然根节点下面的左右子树分开)当做新的根节点并在中序序列中查找位置,不断如此递归,把中序不断分开,当递归完左子树之后,同样如此递归右子树,当然,在每次这样的过程中,我们需要同时保存数据,建立二叉树。
如果有树:前序为ABDGHCEIF ,中序为:GDHBAEICF。
按照以上意思,A为第一次递归根节点,中序分为:GDHB AEICF;
第二次递归 B为在中序中查找的节点 分为:GDH
第三次递归 D为在中序中查找的节点 分为:G H
接着G,后面没了,左边递归完成,G为左子树最后一个叶子节点,然后回溯。。。。
右子树是同样的道理,注意,每次我们递归的时候在中间建立了二叉树,并且进行了赋值
代码:
#include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct tree { char value; struct tree *lchild; struct tree *rchild; }Tree; void search(char *preorder, char *pinorder,Tree **first ,int treelen) { int nleftlen,nrightlen; char *pleftend; Tree *p; if(preorder==NULL||pinorder==NULL||first==NULL) return; p=(Tree *)malloc(sizeof(Tree)); p->value=*preorder; //对建立的节点赋值 p->lchild=p->rchild=NULL; //初始化节点左右指针 *first=p; //记录此时根节点 if(treelen==1) return ; pleftend=pinorder; //pletfend得到先序遍历中根节点的值,下面在中序遍历中查找该点的位置 while(*pleftend!=*preorder) pleftend++; nleftlen=(int)(pleftend-pinorder); nrightlen=treelen-nleftlen-1; if(nleftlen>0) //左边递归 search(preorder+1,pinorder,&(p->lchild),nleftlen); if(nrightlen>0) //右边递归 注意指针位置的变化 search(preorder+nleftlen+1,pinorder+nleftlen+1,&(p->rchild),nrightlen); } void Postorder(Tree *p) //树建立完了之后进行后序遍历 { if(p!=NULL) { Postorder(p->lchild); Postorder(p->rchild); printf("%c",p->value); } } int main() { char a[100],b[100]; Tree *p; while(scanf("%s%s",a,b)!=EOF) { search(a,b,&p,strlen(a)); Postorder(p); printf("\n"); } return 0; }
相关文章推荐
- 重建二叉树NYOJ221题 && NYOJ756题
- nyoj221 已知条件构造二叉树
- nyoj221 nyoj756 重建二叉树
- 【二叉树】已知二叉树前序序列和中序序列,重建唯一二叉树
- 已知二叉树的前序和中序,重建二叉树_笔记
- 已知二叉树的前序遍历和中序遍历的结果,重建二叉树
- NYOJ 题目756 重建二叉树
- 重建二叉树--已知一个二叉树的前、中序排列,重建出该二叉树。
- 【二叉树】已知二叉树前序序列和中序序列,重建唯一二叉树
- 已知二叉树的前序遍历和中序遍历重建二叉树(二叉树)
- 已知中序遍历和先序遍历重建二叉树
- 已知二叉树前序遍历和中序遍历的结果,重建二叉树
- 二叉树的重建 已知前序 中序 求后序 递归的方法
- nyoj-756-重建二叉树
- NYOJ-756重建二叉树
- 已知前序中序,重建二叉树(加7种遍历的方式)
- nyoj 1063 - 生活的烦恼 二叉树重建及遍历
- 已知前序遍历和中序遍历,重建二叉树
- 已知二叉树的后序遍历和中序遍历重建二叉树(二叉树)
- 剑指Offer算法题之已知两种遍历方式重建二叉树--面试题6:重建二叉树