您的位置:首页 > 其它

1119. Pre- and Post-order Traversals (30)解题报告

2016-12-31 20:56 513 查看
前序遍历是MLR,后序遍历是LRM。
前序的第一个元素和后续遍历的后一个元素就是根结点。
如果在子序列中前序的第一个元素等于后序的最后一个元素,那么存在多解。本程序中遇到有多种可能时,都把子序列挂到父节点的左边。
如果子序列中前序的第一个元素不等于后序的最后一个元素,那么前者是父节点的左孩子,后者是父节点的右孩子。
父节点的左孩子在后序遍历中位于L的最后一位。
父节点的右孩子在前序遍历中位于R第一位。由此可得到L的元素数量和R的元素数量。
第一个版本

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <set>

using namespace std;

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

void recovery(int start1, int start2, int cnt, node *&root);
void inorder(node *root);
int	pre[40], post[40];
bool flag = true;
queue<int> in;
int main(void)
{
int	i, n;
node *root;
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%d", pre + i);
}
for (i = 0; i < n; i++) {
scanf("%d", post + i);
}
root = new node;
root->key = pre[0];
root->left = root->right = nullptr;
recovery(1, 0, n - 1, root);
if (flag) {
puts("Yes");
}
else {
puts("No");
}
inorder(root);
printf("%d", in.front());
in.pop();
while (!in.empty()) {
printf(" %d", in.front());
in.pop();
}
putchar('\n');
return 0;
}

void recovery(int start1, int start2, int cnt, node *&r) {
node *root = nullptr;
if (cnt < 1) {
return;
}
else if (pre[start1] == post[start2 + cnt - 1]) {
flag = false;
root = new node;
root->left = root->right = nullptr;
root->key = pre[start1];
r->left = root;
recovery(start1 + 1, start2, cnt - 1, root);
}
else if (pre[start1] != post[start2 + cnt - 1]) {
int i, j, preleft, num;
preleft = pre[start1];
for (i = start2; i < start2 + cnt; i++) {
if (post[i] == preleft) {
break;
}
}
num = i - start2 + 1;
node *left, *right;
left = new node;
right = new node;
left->key = pre[start1];
right->key = post[start2 + cnt - 1];
left->left = left->right = right->left = right->right = nullptr;
r->left = left;
r->right = right;
recovery(start1 + 1, start2, num - 1, left);
recovery(start1 + num + 1, start2 + num, cnt - 1 - num, right);
}
}

void inorder(node *root) {
if (root) {
inorder(root->left);
in.push(root->key);
inorder(root->right);
}
}


第二个版本

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <set>

using namespace std;

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

void recovery(int start1, int start2, int cnt, node *&root);
void inorder(node *root);
int	pre[40], post[40];
bool flag1 = true, flag2 = true;
queue<int> in;
int main(void)
{
int	i, n;
node *root;
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%d", pre + i);
}
for (i = 0; i < n; i++) {
scanf("%d", post + i);
}
root = nullptr;
recovery(0, 0, n, root);
if (flag2) {
puts("Yes");
}
else {
puts("No");
}
inorder(root);
printf("%d", in.front());
in.pop();
while (!in.empty()) {
printf(" %d", in.front());
in.pop();
}
putchar('\n');
return 0;
}

void recovery(int start1, int start2, int cnt, node *&r) {
node *root = nullptr;
if (cnt < 1) {
return;
}
else if (pre[start1] == post[start2 + cnt - 1]) {
flag2 = flag1;
flag1 = false;
if (r == nullptr) {
r = new node;
r->key = pre[start1];
r->left = r->right = nullptr;
recovery(start1 + 1, start2, cnt - 1, r);
}
else {
root = new node;
root->left = root->right = nullptr;
root->key = pre[start1];
r->left = root;
recovery(start1 + 1, start2, cnt - 1, root);
}
}
else if (pre[start1] != post[start2 + cnt - 1]) {
int i, j, preleft, num;
preleft = pre[start1];
for (i = start2; i < start2 + cnt; i++) {
if (post[i] == preleft) {
break;
}
}
num = i - start2 + 1;
node *left, *right;
left = new node;
right = new node;
left->key = pre[start1];
right->key = post[start2 + cnt - 1];
left->left = left->right = right->left = right->right = nullptr;
r->left = left;
r->right = right;
recovery(start1 + 1, start2, num - 1, left);
recovery(start1 + num + 1, start2 + num, cnt - 1 - num, right);
}
}

void inorder(node *root) {
if (root) {
inorder(root->left);
in.push(root->key);
inorder(root->right);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: