1. 程式人生 > >PTAL2-004 這是二叉搜尋樹嗎解題報告---二叉搜尋樹的建立 & 左右節點交換 & 先序 & 後序遍歷

PTAL2-004 這是二叉搜尋樹嗎解題報告---二叉搜尋樹的建立 & 左右節點交換 & 先序 & 後序遍歷

                           L2-004 這是二叉搜尋樹嗎?(25 分)

一棵二叉搜尋樹可被遞迴地定義為具有下列性質的二叉樹:對於任一結點,

  • 其左子樹中所有結點的鍵值小於該結點的鍵值;
  • 其右子樹中所有結點的鍵值大於等於該結點的鍵值;
  • 其左右子樹都是二叉搜尋樹。

所謂二叉搜尋樹的“映象”,即將所有結點的左右子樹對換位置後所得到的樹。

給定一個整數鍵值序列,現請你編寫程式,判斷這是否是對一棵二叉搜尋樹或其映象進行前序遍歷的結果。

輸入格式:

輸入的第一行給出正整數 N(≤1000)。隨後一行給出 N 個整數鍵值,其間以空格分隔。

輸出格式:

如果輸入序列是對一棵二叉搜尋樹或其映象進行前序遍歷的結果,則首先在一行中輸出 YES ,然後在下一行輸出該樹後序遍歷的結果。數字間有 1 個空格,一行的首尾不得有多餘空格。若答案是否,則輸出 NO

輸入樣例 1:

7
8 6 5 7 10 8 11

輸出樣例 1:

YES
5 7 6 8 11 10 8

輸入樣例 2:

7
8 10 11 8 6 7 5

輸出樣例 2:

YES
11 8 10 7 5 6 8

輸入樣例 3:

7
8 6 8 5 10 9 11

輸出樣例 3:

NO

考查對二叉搜尋樹的基本理解 

 AC Code:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<string>
#include<cctype>
#include<map>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#define INF 0x3f3f3f3f
using namespace std;
static const int MAX_N = 1e5 + 5;
typedef long long ll;
struct  BST{
	int weight;
	BST *lson, *rson;
};
queue<int> Q1;	//記錄先序遍歷節點
queue<int> Q2;	//記錄後序遍歷節點
void PreOrder(BST *T){	//先序遍歷
	if (!T) return;
	Q1.push(T->weight);
	PreOrder(T->lson);
	PreOrder(T->rson);
}
void LaterOrder(BST *T) {	//後序遍歷
	if (!T) return;
	LaterOrder(T->lson);
	LaterOrder(T->rson);
	Q2.push(T->weight);
}
void insert(BST * &T, int weight) {	//二叉樹的建立
	if (!T) {
		T = (BST *)malloc(sizeof(BST));
		T->weight = weight;
		T->lson = NULL;
		T->rson = NULL;
	}
	else {
		if (weight >= T->weight) {
			insert(T->rson, weight);
		}
		else {
			insert(T->lson, weight);
		}
	}
}
void Swap(BST * &T) {	//交換左右節點
	if (!T) return;
	Swap(T->lson);
	Swap(T->rson);
	BST *temp = T->lson;
	T->lson = T->rson;
	T->rson = temp;
}
int main(){
	int n;
	int vv[1005];
	BST *root = NULL;
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%d", &vv[i]);
		insert(root, vv[i]);
	}
	PreOrder(root);
	bool flag = true;
	for (int i = 0; i < n; i++) {	//二叉樹先序遍歷是否符合輸入順序
		int v2 = Q1.front();
		Q1.pop();
		if (vv[i] != v2) {
			flag = false;
			break;
		}
	}
	while (!Q1.empty()) Q1.pop();
	if (flag) {
		printf("YES\n");
		LaterOrder(root);
		while (Q2.size() > 1) {
			printf("%d ", Q2.front());
			Q2.pop();
		}
		printf("%d\n", Q2.front());
		Q2.pop();
	}
	else {
		Swap(root);		//二叉樹映象
		PreOrder(root);
		flag = true;
		for (int i = 0; i < n; i++) {	//二叉樹映象先序遍歷是否符合輸入順序
			int v2 = Q1.front();
			Q1.pop();
			if (v2 != vv[i]) {	
				flag = false;
				break;
			}
		}
		while (!Q1.empty()) Q1.pop();
		if (flag) {
			printf("YES\n");
			LaterOrder(root);	//後序遍歷 & 列印
			while (Q2.size() > 1) {
				printf("%d ", Q2.front());
				Q2.pop();
			}
			printf("%d\n", Q2.front());
			Q2.pop();
		}
		else printf("NO\n");
	}
	return 0;
}