例题1:
题目大意:
VJ题目链接(这个判定有问题,好像不能判……所以代码不一定正确)
- 现有两个结点序列,分别是对同一个二叉树进行前序遍历和中序遍历的结果。编写程序,输出该二叉树按后序遍历时的结点序列。
输入:
1:输入二叉树结点数n
2:输入前序遍历结点编号序列
3:输入中序遍历结点编号序列
输出:
输出后序遍历结点编号序列
思想:
按 遍历的顺序依次访问各结点。把此时 的结点作为根 ,去 里找到该结点位置 ,那么此时在 左边的就是 的左子树,此时在 右边的就是 的右子树。
例子:
代码:
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
vector <int> inorder;
vector <int> preorder;
vector <int> postorder;
int n, pos;
void rec(int l, int r)
{
if (l >= r)
return;
int root = preorder[pos++];
int m = distance(inorder.begin(), find(inorder.begin(), inorder.end(), root));
rec(l, m);
rec(m + 1, r);
postorder.push_back(root);
}
void solve()
{
pos = 0;
rec(0, n);
for (int i = 0; i < n - 1; i++)
printf("%d ", postorder[i]);
printf("%d\n", postorder[n - 1]);
}
int main()
{
scanf("%d", &n);
inorder.clear();
preorder.clear();
postorder.clear();
int val;
for (int i = 0; i < n; i++)
{
scanf("%d", &val);
preorder.push_back(val);
}
for (int i = 0; i < n; i++)
{
scanf("%d", &val);
inorder.push_back(val);
}
solve();
return 0;
}
例题2:
题目大意:
- 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回
思想:
- 基本就是照着抄上面的那个代码,只不过这次就后序遍历变成了构造树。找到左右结点就好。
代码:
class Solution {
public:
int pos;
TreeNode * rec(int l, int r, vector<int> pre,vector<int> vin)
{
if (l >= r)
return NULL;
TreeNode * root = (TreeNode *) malloc(sizeof(TreeNode));
int val = pre[pos++];
int m = distance(vin.begin(), find(vin.begin(), vin.end(), val));
TreeNode * left = rec(l, m, pre, vin);
TreeNode * right = rec(m + 1, r, pre, vin);
root->left = left;
root->right = right;
root->val = val;
return root;
}
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
if (pre.size() == 0)
return NULL;
pos = 0;
TreeNode * root = rec(0, pre.size(), pre, vin);
return root;
}
};