已知二叉树的两种遍历结果,求另一个遍历结果

其实,并不是已知随意两种遍历结果,就能还原二叉树的,只有已知先序和中序或中序和后序,才能还原二叉树。

1、已知先序:ABCDEFGH,中序:BDCEAFHG,求后序。那么在先序里面,第一个点A肯定是根节点,然后在中序里找到A的位置,划分成两部分,左边为BDCE,右边为FHG,那么A的左子树上肯定是BDCE,在先序里面B的位置最靠前,那么B就是BDCE这四个点的根节点,然后继续划分,B的左边没有节点了,那么DCE就全在B的右子树上,然后按照刚才找根节点的方法继续找就可以了,直到叶子节点。

在找某几个点的组合中根节点的时候,根据先序找对应下标最小的。

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
int pos[30], l[30], r[30];
char pre[30], in[30];
void dfs(int left, int right, int root, int f, int dir) {
	if(left > right) return ;
	if(left == right) {
		if(f != -1 && dir != -1) {
			if(dir == 0) {
				l[f] = in[left] - 'A';
			} else {
				r[f] = in[left] - 'A';
			}
		}
		return ;
	}
	int id = pos[pre[root] - 'A'];
	int x = in[id] - 'A';
	if(f != -1 && dir != -1) {
		if(dir == 0) {
			l[f] = x;
		} else {
			r[f] = x;
		}
	}
	dfs(left, id - 1, root + 1, x, 0);
	dfs(id + 1, right, root + 1 + id - left, x, 1);
}
void post_order(int x) {
	if(l[x] != -1) post_order(l[x]);
	if(r[x] != -1) post_order(r[x]);
	printf("%c", x + 'A');
}
int main() {
	scanf("%s%s", pre, in);
	int len = strlen(in);
	for(int i = 0; i < len; i++) {
		int x = in[i] - 'A';
		pos[x] = i;
	}
	memset(l, -1, sizeof l);
	memset(r, -1, sizeof r);
	dfs(0, len - 1, 0, -1, -1);
	post_order(pre[0] - 'A');
	printf("\n");
	return 0;
}

2、已知后序:DECBHGFA,中序:BDCEAFHG,求先序。在后序里面A必定是根节点,那么在中序里面找到A,划分为左右子树,过程跟上面说过的类似,只不过在找某几个点的根节点的时候,是在后序里面找位置最靠后的,即对应下标最大的。

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
int pos[30], l[30], r[30];
char post[30], in[30];
void dfs(int left, int right, int root, int f, int dir) {
	if(left > right) return ;
	if(left == right) {
		if(f != -1 && dir != -1) {
			if(dir == 0) {
				l[f] = in[left] - 'A';
			} else {
				r[f] = in[left] - 'A';
			}
		}
		return ;
	}
	int id = pos[post[root] - 'A'];
	int x = in[id] - 'A';
	if(f != -1 && dir != -1) {
		if(dir == 0) {
			l[f] = x;
		} else {
			r[f] = x;
		}
	}
	dfs(left, id - 1, root - 1 - right + id, x, 0);
	dfs(id + 1, right, root - 1, x, 1);
}
void pre_order(int x) {
	printf("%c", x + 'A');
	if(l[x] != -1) pre_order(l[x]);
	if(r[x] != -1) pre_order(r[x]);
}
int main() {
	scanf("%s%s", post, in);
	int len = strlen(in);
	for(int i = 0; i < len; i++) {
		int x = in[i] - 'A';
		pos[x] = i;
	}
	memset(l, -1, sizeof l);
	memset(r, -1, sizeof r);
	dfs(0, len - 1, len - 1, -1, -1);
	pre_order(post[len - 1] - 'A');
	printf("\n");
	return 0;
}
发布了150 篇原创文章 · 获赞 4 · 访问量 6939

猜你喜欢

转载自blog.csdn.net/Napom/article/details/103149618
今日推荐