心中有树(雾)

首先我们知道树表示了一种一对多的结构,二叉树就是一种一对二的结构;
其次我们知道遍历树的方法除了层序遍历,利用根和左右孩子的关系有六种遍历方式。但是人为规定左孩子到右孩子的顺序就只有三种遍历方式,根据根的位置分别是前序遍历(根左右),中序遍历(左根右),后序遍历(左右根)。
那么就可以很清楚的知道前序+中序–>后序,或者后序+中序–>前序;
以前序+中序–>后序为例:
大概思路就是说前序可以确定根,结合中序可以退出根的左子树和右子树,在递归的进行上述操作直到叶子结点返回到调用位置。
废话不多说,我们来看例题:
题目链接:<–一定要点开啊

Binary Tree Traversals Time Limit: 1000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11697
Accepted Submission(s): 5208

Problem Description A binary tree is a finite set of vertices that is
either empty or consists of a root r and two disjoint binary trees
called the left and right subtrees. There are three most important
ways in which the vertices of a binary tree can be systematically
traversed or ordered. They are preorder, inorder and postorder. Let T
be a binary tree with root r and subtrees T1,T2.

In a preorder traversal of the vertices of T, we visit the root r
followed by visiting the vertices of T1 in preorder, then the vertices
of T2 in preorder.

In an inorder traversal of the vertices of T, we visit the vertices of
T1 in inorder, then the root r, followed by the vertices of T2 in
inorder.

In a postorder traversal of the vertices of T, we visit the vertices
of T1 in postorder, then the vertices of T2 in postorder and finally
we visit r.

Now you are given the preorder sequence and inorder sequence of a
certain binary tree. Try to find out its postorder sequence.

Input The input contains several test cases. The first line of each
test case contains a single integer n (1<=n<=1000), the number of
vertices of the binary tree. Followed by two lines, respectively
indicating the preorder sequence and inorder sequence. You can assume
they are always correspond to a exclusive binary tree.

Output For each test case print a single line specifying the
corresponding postorder sequence.

Sample
Input 9 1 2 4 7 3 5 8 9 6 4 7 2 1 8 5 9 3 6

Sample Output 7 4 2 8 9 5 6 3 1

题目大意:给前序和中序推出后序 嗯 ,就是这么简洁明了,有兴趣的自行百度题目背景
解题思路:可能是因为思维定式,建树的过程就是利用指针+递归嘛~但是其实数组模拟,传数组的地址就可以了,不用很复杂的,还记得我无数次利用指针结果wa了无数发之后re了无数发的惨痛经历,现在觉得自己真的好傻好天真。
也就是说我在前序中找到根节点在中序中找到左右两棵子树的范围,然后递归到左子树,这是的根节点就是前序中第二个的位置,以此类推,所以我可以传两个数组的地址,前序的地址不断的加一,中序的地址找到根节点确定范围,传地址和范围即可。
AC代码:

#include<iostream>
#include<cstring>
using namespace std;
int n;//结点个数
int pre[1010],in[1010],cnt=0;//前序,中序,计数用来控制输出格式的
void creat(int *a,int *b,int c){//a-->前序b-->中序c-->结点个数
    if(c<=0)return ;//如果结点个数已经小于或者等于0了说明该区间已经没有结点就直接返回啊
    int t;//记录根的坐标
    for(int i=0;i<c;i++)//找根
        if(b[i]==*a) {t=i;break;}
    creat(a+1,b,t);//左子树的区间
    creat(a+1+t,b+t+1,c-t-1);//右子树的区间
    t=*a;//根
    if(cnt>0) cout<<" ";
    cout<<t;
    ++cnt;
}
int main(){
    while(cin>>n){
        memset(pre,0,sizeof(pre));
        memset(in,0,sizeof(in));
        for(int i=0;i<n;i++) cin>>pre[i];
        for(int i=0;i<n;i++) cin>>in[i];
        cnt=0;
        creat(pre,in,n);
        cout<<endl;
    }
}

彩蛋<–相信我,彩蛋很有趣;

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值