1119.(重、错)Pre- and Post-order Traversals

时间:2023-03-10 02:16:59
1119.(重、错)Pre- and Post-order Traversals

题目大意:

给定一棵树的结点个数n,以及它的前序遍历和后序遍历,输出它的中序遍历;

如果中序遍历不唯一就输出No,且输出其中一个中序即可,如果中序遍历唯一就输出Yes,并输出它的中序

思路:(转载

先序+后序 无法判断二叉树的唯一性

  • 先序第一个节点是根节点,紧接着第二个节点是根节点的左节点还是右节点?
  • 在后序中查找 先序中的第二个节点,
  1. 如果后序中的该位置 到 最后(也就是后序中根节点位置) 还有其他数的话,可以判断,先序中第二个节点肯定左节点(反证法。。。)
  2. 当中间没有数的时候,就不确定了

例如:

前序序列:
后序序列: 为 根, 接着,2在后序中,与1隔着两个数,所以2一定是1的左节点; ,4成为1的右子树节点
#include<bits/stdc++.h>
using namespace std;
int n;
bool isUnique = true;
vector<int> preOrder, in, postOrder; struct Node {
int val;
Node* lchild, *rchild;
Node(int _val = -){
val = _val;
lchild = NULL;
rchild = NULL;
} }; Node* Create(int preL, int preR, int postL, int postR)
{
Node* root = new Node(preOrder[preL]);
if (preL == preR) return root;
int k;
for (k = postL; k < postR; k++){ // 后序找 pre[preL + 1]
if (postOrder[k] == preOrder[preL + ]) break;
}
// 在后序中查找 先序中的第二个节点
// 如果后序中的该位置 到 最后(也就是后序中根节点位置) 还有其他数的话,
// 可以判断,先序中第二个节点肯定左节点(反证法。。。)
if (postR - k - > ){
int numLeft = k - postL + ;
root->lchild = Create(preL + , preL + numLeft, postL, k);
root->rchild = Create(preL + + numLeft, preR, k + , postR - );
}
else {
isUnique = false;
//假定第二个节点是根节点的右节点
root->rchild = Create(preL + , preR, postL, postR - );
}
return root;
} void inOrder(Node* root){
if (root != NULL){
inOrder(root->lchild);
in.push_back(root->val);
inOrder(root->rchild);
}
} int main()
{
scanf("%d", &n);
preOrder.resize(n);
postOrder.resize(n);
for (int i = ; i < n; i++) scanf("%d", &preOrder[i]);
for (int i = ; i < n; i++) scanf("%d", &postOrder[i]);
Node* root = Create(, n - , , n - );
inOrder(root);
printf("%s\n%d", isUnique == true ? "Yes" : "No", in[]);
for (int i = ; i<n; i++) printf(" %d", in[i]);
printf("\n");
return ;
}