浙大数据结构习题笔记:03-树3 Tree Traversals Again (25分)

03-树3 Tree Traversals Again (25分)

在这里插入图片描述
在这里插入图片描述

分析

看了下视频解析,觉得除了常规的借助先序与中序遍历把这棵树重新构造出来再遍历外,视频中借助规律和递归分治法真的是很简洁。
主函数中,在题中可以明白,Push进去的是先序的内容,Pop出去的是中序的内容,这样遍历完成所有输入后,可以得到pre in两个代表先序与后序遍历的数组。
之后,关键是围绕着这两个数组找出后序post的顺序,我们发现一些规律:
先序遍历中:根一定是第一项
中序遍历中:根的左右分别代表左右子树
后序遍历中:根一定是最后一项
这样我们可以用递归的思想来做。
首先可以通过先序找到根节点,首先将后序的最后一项填成根节点。
之后通过一层在中序中的遍历,通过找到中序的根结点的方式,我们可以知道根的左右子树所代表的数目。
接着,通过递归法,控制变量数目(具体数学实现见下图)
直到n == 1时,一定知道只有一个根,与先序一样,赋值
再加上一个n==0防错
在这里插入图片描述

具体代码实现

#include <iostream>
#include <stack>
#include <string>
#define MAX 100
using namespace std;

int pre[MAX],in[MAX],post[MAX];

void solve(int preL,int inL,int postL,int n)
{
    if(n == 0){
        return;
    }
    if(n == 1){
        post[postL] = pre[preL];
        return;
    }
    int i;
    int root = pre[preL];//先序遍历第一个是根
    post[postL+n-1] = root;//后序遍历最后一个是根
    for(i=0;i<n;i++){
        if(in[inL + i] == root)
            break;
        //i——左右分置
    }
    int L=i,R=n-i-1;//L,R为分置的左右数目
    solve(preL+1,inL,postL,L);
    solve(preL+L+1,inL+L+1,postL+L,R);
    //左右分置
}


int main()
{
    int n,num,i=0,j=0,k=0;
    cin >> n;
    string str;
    stack<int> stack;
    for(;k<2*n;k++){
        cin >> str;
        if(str == "Push"){  //Push代表先序遍历
            scanf("%d\n",&num);
            stack.push(num);
            pre[i++] = num; //建立先序表
        }else{  //Pop代表中序遍历
            num = stack.top();
            stack.pop();
            in[j++] = num;  //建立中序表
        }
    }
    solve(0,0,0,n);
    for(i=0;i<n;i++){
        printf("%d",post[i]);
        if(i != n-1){
            printf(" ");
        }
    }
    return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值