noip2001 求先序排列 (已知中序+后序,求解先序 ;分治)

本文介绍了一道NOIP2001普及组的题目,该题要求根据给定的二叉树中序与后序排列求解其先序排列。文章提供了一个简洁的C++代码实现方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A1132. 求先序排列
时间限制: 1.0s   内存限制: 256.0MB  
总提交次数: 188   AC次数: 116   平均分: 68.83
将本题分享到:
       
   
试题来源
  NOIP2001 普及组
问题描述
  给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,长度<=8)。
输入格式
  两行,每行一个字符串,分别表示中序和后序排列
输出格式
  一个字符串,表示所求先序排列
样例输入
BADC
BDCA
样例输出
ABCD


解析:用string x记录整个二叉树的中序排列,string y 记录整个二叉树的后序排列。

         write(L1,R1,L2,R2)表示输出一个中序排列为x[L1]-x[R1],后序排列为y[L2]-y[R2]的二叉树的前序排列。

代码:

#include<iostream>
#include<cstdio>
#include<string>
using namespace std; 
string x,y;

void write(int p,int q,int m,int n)
{
  if(p>q)return;
  if(p==q){cout<<x[p];return;}
  
  int i,j,k;
  k=x.find(y[n]);
  cout<<y[n];
  write(p,k-1,m,m+k-p-1);
  write(k+1,q,m+k-p,n-1);
}
int main()
{
  int i,j,k;
  cin>>x>>y;
  k=x.length();
  write(0,k-1,0,k-1);
  return 0;
}



    ### NOIP 2001 03 排列算法解析 对于给定的中遍历和后序遍历序列,可以通过递归的方式还原二叉树并输出其遍历结果。以下是基于此问题的具体实现方法。 #### 方法概述 通过分析已知条件中的中遍历和后序遍历序列,可以得出以下结论: - **后序遍历**的最后一个节点必然是当前子树的根节点。 - 利用该根节点,在**中遍历**中定位其位置,则可划分出左子树和右子树对应的区间[^3]。 随后按照上述逻辑递归处理左右子树即可完成整个二叉树结构的重建,并最终得到遍历的结果。 #### 实现代码 (C++) 下面是具体的 C++ 实现代码: ```cpp #include <bits/stdc++.h> using namespace std; string zhong, hou; // 定义全局变量存储中后序遍历字符串 void deal(int l1, int r1, int l2, int r2) { // 参数解释:l1 和 r1 表示中遍历区间的起始与结束;l2 和 r2 表示后序遍历区间的起始与结束 if (l1 > r1 || l2 > r2) return; // 输出当前子树的根节点(即后序遍历最后一位) cout << hou[r2]; // 找到根节点在中遍历中的索引位置 int pos = -1; for (int i = l1; i <= r1; ++i) { if (zhong[i] == hou[r2]) { pos = i; break; } } // 处理左子树 deal(l1, pos - 1, l2, l2 + pos - 1 - l1); // 处理右子树 deal(pos + 1, r1, r2 - r1 + pos, r2 - 1); } int main() { cin >> zhong >> hou; // 输入中后序遍历序列 int len = hou.length(); deal(0, len - 1, 0, len - 1); // 调用函数进行计算 return 0; } ``` 以上程实现了从输入的中后序遍历序列出发,逐步恢复原二叉树的过程,并按打印各结点值[^4]。 --- ### 关键点说明 1. **递归终止条件**: 当前子树为空时停止进一步分解操作; 2. **根节点确定方式**: 始终以后续遍历数组末位作为当前层树形结构之首部元素; 3. **分割策略**: 根据找到的根节点于中间次序列表里确切座标来界定左右分支界限范围[^3]. 这些要点共同构成了高效解决此类题目所需的核心思路和技术手段。 ---
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值