HDU1710 Binary Tree Traversals【树的遍历】

题目地址
Binary Tree Traversals
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5565 Accepted Submission(s): 2590

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

刚好给徒弟码了一下这个,顺便贴出来备忘。
简单的数据结构问题,按他说的做就行。
不过这里使用的是利用数组和下标来代替指针建树。
算是摆脱指针的一个小伎俩?

#include<cstdio>
struct node
{
    int w;//树的值 
    int l,r;//左右儿子的下标,-1表示不存在 
};
node tree[2005];//树的本体
//在这里,下标就相当于原先的指针 
int top;//当前树有多少个点,初始化为0
int New(int a)//代替new的功能新建一个点 返回当前新建的点的下标 
{
    tree[top].w=a;//给新建的节点赋值 
    tree[top].l=-1;//新建的节点的左右儿子均不存在所以赋值为-1 
    tree[top].r=-1;
    top++;//树的点数增加1 
    return top-1; 
}
//四个参数分别为:该子树前序遍历的起点(第一位), 该子树前序遍历的终点(最后一位加一), 该子树中序遍历的起点(第一位), 该子树中序遍历的终点(最后一位加一)
//返回值为该子树的根结点的下标 
int Create(int *aleft,int *aright,int *bleft,int *bright)
{
    if(aright==aleft)return -1;//当进来的遍历长度为0时,表示该树为空,于是返回-1 
    if(aright-aleft==1)return New(*aleft);//当进来的遍历长度为1时表示只有一个点,此时不需要递归建树,直接新建该点即可 
    int ret=New(*aleft);//先将该子树的根new出来并储存它的下标 
    for(int *i=bleft;i!=bright;i++)//从头开始扫一遍中序遍历找根 
    {
        if(*i==*aleft)//找到根了,那么就将前序遍历和中序遍历划成两块,也就是左右子树,然后递归建树 
        {
            //递归建树的返回值即为该子树两个儿子的下标 
            tree[ret].l=Create(aleft+1,aleft+(i-bleft)+1,bleft,i);
            tree[ret].r=Create(aleft+(i-bleft)+1,aright,i+1,bright);
            break;
        }
    } 
    return ret;//返回该子树的根结点的下标 
} 
bool flag;//判断是否需要输出空格 辣鸡格式 
void LRD(int p)//递归进行后序遍历,p为当前根的下标 
{
    //注意要判断有没有左右儿子 
    if(tree[p].l!=-1)LRD(tree[p].l);
    if(tree[p].r!=-1)LRD(tree[p].r);
    if(flag)printf(" ");
    else flag=true;
    printf("%d",tree[p].w);
}
int main()
{
    int n;
    while(scanf("%d",&n)==1)
    {
        top=0;//这一步就相当于把整棵树清空 
        int a[2005],b[2005];
        for(int i=0;i<n;i++)scanf("%d",&a[i]);
        for(int i=0;i<n;i++)scanf("%d",&b[i]);
        int root=Create(a,a+n,b,b+n);
        flag=false;
        LRD(root);
        printf("\n");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值