已知二叉樹的兩種遍歷結果,求另一個遍歷結果

其實,並不是已知隨意兩種遍歷結果,就能還原二叉樹的,只有已知先序和中序或中序和後序,才能還原二叉樹。

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章