PAT A1086 Tree Traversals Again [二叉树前序中序求后序]

题目描述

链接
用栈的形式给出一棵二叉树的建立的顺序,求这棵二叉树的后序遍历

分析

  • 性质:树的先序等于入栈次序,树的中序遍历等于出栈次序
    • 先序:先访问根再入栈,所以入栈次序就是先序遍历次序
    • 中序:先递归访问左子树,回溯时访问根,回溯时即出栈时,所以出栈次序就是中序遍历
  • 所以问题转换为已知先序中序,求后序
  • 已知先序中序求后序的方法
    • \(root\) 保存先序中根的位置,\(st\)\(ed\) 为中序子树的起始结束位置
    • 遍历中序,找到中序根的位置\(i\),从而分成左右子树
    • 左子树在先序中根的位置\(root+1\) ,右子树在先序中根的位置\(root+左子树结点数\)
    • 在中序中找左子树结点数\(i-st+1\) ,右子树根位置:\(root+i-st+1\)
    • 求后序:就是先左右递归dfs,再访问根
void dfs(int root, int st, int ed){
    if(st > ed) return; //中序长度小于等于0
    int i = st;
    while(i<=st&&in[i]!=pre[root]) i++;
    dfs(root+1, st, i-1);
    dfs(root+i-st+1, i+1, ed);
    ans.push_back(pre[root]);
}
  • 求层序遍历
    • 加一个变量\(index\) ,表示当前根结点在二叉树中所对应的下标(从0开始),左子树\(2*index+1\) ,右子树\(2*index+2\) (因为下标从0开始,不是从1开始)
    • 输出先序的递归的时候,把节点的\(index\)\(value\)放进结构体里,再装进\(vector\)
    • 在递归完成后,\(vector\)中按照\(index\)排序就是层序遍历的顺序
struct node {
    int index, value;
};
bool cmp(node a, node b) {
    return a.index < b.index;
}
vector<int> post, in;
vector<node> ans;
void dfs(int root, int st, int ed, int idx) {
    if (st > ed) return;
    int i = st;
    while (i <= end && in[i] != post[root]) i++;
    ans.push_back({idx, post[root]});
    dfs(root - 1 - ed + i, st, i - 1, 2 * idx + 1);
    dfs(root - 1, i + 1, ed, 2 * idx + 2);
}
pre(n - 1, 0, n - 1, 0);
sort(ans.begin(), ans.end(), cmp);
  • 为了避免树中多个值相同,会出问题,故先序,中序后序都保存的是\(key\) ,用\(value\) 保存实际的值

完整代码

#include<bits/stdc++.h>
using namespace std;

vector<int> pre, in, post, value;
stack<int> s;
int n,num,key;
char str[10];
//先序对应入栈,中序对应出栈
//一直先序,中序,求后序
void dfs(int root, int st, int ed){
    if(st > ed) return;
    int i = st;
    while(i<=ed && in[i] != pre[root]) i++;
    //左右根
    dfs(root+1, st, i-1);
    dfs(root+(i-st+1), i+1, ed);
    post.push_back(pre[root]);
}
int main(){
    scanf("%d",&n);
    while(~scanf("%s", str)){
        if(strlen(str) == 4){
            scanf("%d",&num);
            pre.push_back(key); //前中后序均保存key,避免值相同而出现问题
            value.push_back(num);
            s.push(key++);
        }else{
            in.push_back(s.top());
            s.pop();
        }
    }
    dfs(0, 0, n-1);
    for(int i=0;i<post.size();i++){
        if(i==0) printf("%d",value[post[i]]);
        else printf(" %d",value[post[i]]);
    }
    printf("\n");

}

转载于:https://www.cnblogs.com/doragd/p/11284500.html

内容概要:本文详细探讨了基于MATLAB/SIMULINK的多载波无线通信系统仿真及性能分析,重点研究了以OFDM为代表的多载波技术。文章首先介绍了OFDM的基本原理和系统组成,随后通过仿真平台分析了不同调制方式的抗干扰性能、信道估计算法对系统性能的影响以及同步技术的实现与分析。文中提供了详细的MATLAB代码实现,涵盖OFDM系统的基本仿真、信道估计算法比较、同步算法实现和不同调制方式的性能比较。此外,还讨论了信道特征、OFDM关键技术、信道估计、同步技术和系统级仿真架构,并提出了未来的改进方向,如深度学习增强、混合波形设计和硬件加速方案。; 适合人群:具备无线通信基础知识,尤其是对OFDM技术有一定了解的研究人员和技术人员;从事无线通信系统设计与开发的工程师;高校通信工程专业的高年级本科生和研究生。; 使用场景及目标:①理解OFDM系统的工作原理及其在多径信道环境下的性能表现;②掌握MATLAB/SIMULINK在无线通信系统仿真中的应用;③评估不同调制方式、信道估计算法和同步算法的优劣;④为实际OFDM系统的设计和优化提供理论依据和技术支持。; 其他说明:本文不仅提供了详细的理论分析,还附带了大量的MATLAB代码示例,便于读者动手实践。建议读者在学习过程中结合代码进行调试和实验,以加深对OFDM技术的理解。此外,文中还涉及了一些最新的研究方向和技术趋势,如AI增强和毫米波通信,为读者提供了更广阔的视野。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值