0
点赞
收藏
分享

微信扫一扫

A1138 Postorder Traversal (25 分| 树的遍历| 前序中序转后序,附详细注释,逻辑分析)


写在前面

  • 思路分析1
  • ​​后序遍历的顺序是先左右再树根​​
  • 左子树不为空,答案一定在左子树
  • 否则右子树不为空,答案一定在右子树
  • 否则答案为根结点。
  • 思路分析2
  • 递归生成后序结果
  • ​​思路分析3​​
  • 构建树
  • 后序遍历
  • 知识盲点,仅懂部分待深入学习

测试用例

input:
7
1 2 3 4 5 6 7
2 3 1 5 4 7 6

output:
3

ac代码

  • 参考代码1,不太懂
  • 前序中序转后序,只需要知道后序第1个值
  • 定义1个变量flag,当post的第1个值输出,则flag为true
  • 递归出口处判断flag,提前return

#include <iostream>
#include <vector>
using namespace std;
vector<int> pre, in;
bool flag = false;
void postOrder(int prel, int inl, int inr)
{
if(inl > inr || flag == true) return;
int i=inl;
while( in[i] != pre[prel]) i++;
postOrder(prel+1, inl, i-1);
postOrder(prel+i-inl+1, i+1, inr);
if(flag == false)
{
printf("%d", in[i]);
flag = true;
}
}

int main()
{
int n;
scanf("%d", &n);
pre.resize(n);
in.resize(n);
for(int i=0; i<n; i++) scanf("%d", &pre[i]);
for(int i=0; i<n; i++) scanf("%d", &in[i]);
postOrder(0, 0, n-1);

return 0;
}

  • 参考代码2
  • ​​知识点​​
  • 前序中序
  • 算法是使用辅助递归函数,辅助函数需要记录前序数组的起点和中点,数组均使用前闭后闭约定。
  • 中序左子数的区间为[inStart,inRoot-1],中序右子数的区间为[inRoot+1,inEnd]
  • 前序左子数的区间为[preStart+1,preStart+(inRoot-1-inStart)+1] // 由前序左子数的个数等于中序左子树计算得到
  • 前序右子数的区间为[preStart+(inRoot-inStart)+1,preEnd]
  • 中序后序
  • 中序左子数的区间为[inStart,inRoot-1],中序右子数的区间为[inRoot+1,inEnd]
  • 后序左子数的区间为[posStart,posStart+inRoot-1-inStart],
  • 后序右子数的区间为[posStart+inRoot-inStart,posEnd-1]

#include<iostream>
#include<vector>
using namespace std;
vector<int> pre, in,post;

void findRoot(int pl, int pr, int il, int ir) {
if (pl > pr)
return;
int index = il;
while (index<ir&&in[index] != pre[pl])
index++;

//left
findRoot(pl + 1, index-1-il+pl+1, il, index - 1);

//right
findRoot(pr-(ir-index-1), pr, index + 1, ir);

post.push_back(pre[pl]);
}

int main() {
//read
int n;
cin >> n;
pre.resize(n), in.resize(n);
for (int i = 0; i < n; ++i)
cin >> pre[i];
for (int i = 0; i < n; ++i)
cin >> in[i];

findRoot(0, n-1, 0, n-1);
cout << post[0] << endl;
system("pause");
return 0;
}

  • 参考代码3

#include<iostream>
#include<vector>
using namespace std;
vector<int> pre, in,post;

struct node {
int val;
struct node *left, *right;
};

node* buildTree(int pl, int pr, int il, int ir) {
if (pl > pr)
return NULL;
node *root = new node;
root->val = pre[pl];
root->left = root->right = NULL;
int index = il;
while (il <= ir && in[index] != pre[pl])
index++;
root->left = buildTree(pl+1, index-1-il+pl+1, il, index - 1);
root->right = buildTree(pr-(ir-index-1), pr, index + 1, ir);
return root;
}

void dfs(node *root) {
if (root == NULL)
return;
dfs(root->left);
dfs(root->right);
post.push_back(root->val);
}

int main() {
//read
int n;
cin >> n;
pre.resize(n), in.resize(n);
for (int i = 0; i < n; ++i)
cin >> pre[i];
for (int i = 0; i < n; ++i)
cin >> in[i];

node* root = NULL;
root=buildTree(0, n - 1, 0, n - 1);

dfs(root);

cout << post[0] << endl;

system("pause");
return 0;
}


举报

相关推荐

【PAT】1138 Postorder Traversal (25 分)

0 条评论