算法笔记---二叉查找树的性质

题目描述

给出N个正整数来作为一棵二叉排序树的结点插入顺序,问:这串序列是否是该二叉排序树的先序序列或是该二叉排序树的镜像树的先序序列。所谓镜像树是指交换二叉树的所有结点的左右子树而形成的树(也即左子树所有结点数据域大于或等于根结点,而根结点数据域小于右子树所有结点的数据域)。如果是镜像树,则输出YES,并输出对应的树的后序序列;否则,输出NO。

输入样例1
7
8 6 5 7 10 8 11
输出样例1
YES
5 7 6 8 11 10 8
输入样例2
8 10 11 8 6 7 5
输出样例2
YES
11 8 10 7 5 6 8
输入样例3
8 6 8 5 10 9 11
输出样例3
No

解题思路:
保存输入序列origin
先构造一棵二叉排序树(二叉查找树),然后求出
前序遍历pre
镜像前序遍历preM
后序遍历post
镜像后序遍历postM
然后分别比较origin和pre ,preM,若相等,则输出后序遍历或者镜像后序遍历序列

#include<iostream>
using namespace std;
#include<queue>
#include <vector>

//结点定义
struct node
{
	int data;//数据域
	int layer;//层次
	node* lchild;
	node* rchild;
};

//先序遍历
void pre_order(node* root) {
	if (root == NULL)
	{
		return;
	}
	cout << root->data << endl;
	pre_order(root->lchild);
	pre_order(root->rchild);
}

//中序遍历
void in_order(node* root) {
	if (root == NULL)
	{
		return;
	}
	in_order(root->lchild);
	cout << root->data << endl;
	in_order(root->rchild);
}

//后序遍历
void post_order(node* root) {
	if (root == NULL)
	{
		return;
	}
	post_order(root->lchild);
	post_order(root->rchild);
	cout << root->data << endl;
}

//层次遍历且计算每个结点所在层次
void layer_order(node* root) {
	if (root == NULL)
	{
		return;
	}
	queue<node*> q;
	root->layer = 1;
	q.push(root);
	while (!q.empty())
	{
		node* top = q.front();
		q.pop();
		cout << top->data << endl;
		if (top->lchild)
		{
			//左孩子的层号 = 当前层号 + 1
			top->lchild->layer = top->layer + 1;
			q.push(top->lchild);
		}
		if (top->rchild)
		{
			top->rchild->layer = top->layer + 1;
			q.push(top->rchild);
		}
	}
}

//求树的高度
int tree_height(node* root) {
	if (root == NULL)
	{
		return 0;
	}
	int left_height, right_height;
	left_height = tree_height(root->lchild);
	right_height = tree_height(root->rchild);
	if (left_height > right_height)
	{
		return left_height + 1;
	}
	else
	{
		return right_height + 1;
	}
}
//根据先序和中序构建二叉树
node* reConstructBinaryTree(vector<int> pre, vector<int> vin) {
	if (pre.empty() || vin.empty() || pre.size() != vin.size())
	{
		return NULL;
	}
	vector<int> pre_left, pre_right, vin_left, vin_right;
	int i = 0;
	for (i = 0; i < vin.size(); i++)
	{
		if (pre[0] == vin[i])
		{
			break;
		}
		//构造先序遍历和中序遍历的左子树
		pre_left.push_back(pre[i + 1]);
		vin_left.push_back(vin[i]);
	}
	for (int j = i + 1; j < vin.size(); j++)
	{
		pre_right.push_back(pre[j]);
		vin_right.push_back(vin[j]);
	}
	node* root = new node;
	root->data = pre[0];
	root->lchild = reConstructBinaryTree(pre_left, vin_left);
	root->rchild = reConstructBinaryTree(pre_right, vin_right);
	return root;
}

//根据中序和后续遍历来构建二叉树
node* create(vector<int> vin, vector<int> post) {
	if (vin.empty() || post.empty() || vin.size() != post.size())
	{
		return NULL;
	}
	vector<int> vin_left, vin_right, post_left, post_right;
	int i = 0;
	for (i = 0; i < vin.size(); i++)
	{
		if (post[post.size() - 1] == vin[i])
		{
			break;
		}
		vin_left.push_back(vin[i]);
		post_left.push_back(post[i]);
	}
	for (int j = i + 1; j < vin.size(); j++)
	{
		vin_right.push_back(vin[j]);
		post_right.push_back(post[j - 1]);
	}
	node* root = new node;
	root->data = post[post.size() - 1];
	root->lchild = create(vin_left, post_left);
	root->rchild = create(vin_right, post_right);
	return root;
}

//层序遍历
void bfs(node* root) {
	if (root == NULL)
	{
		return;
	}
	queue<node*> q;
	q.push(root);
	while (!q.empty())
	{
		node* top = q.front();
		q.pop();
		cout << top->data << endl;
		if (top->lchild)
		{
			q.push(top->lchild);
		}
		if (top->rchild)
		{
			q.push(top->rchild);
		}
	}
}

//二叉树中和为某一值的路径
vector< vector<int> > find_path(node* root, int number) {
	
	vector< vector<int> > ret;//返回结果
	if (root == NULL)
	{
		return ret;
	}
	vector<int> temp_array;//临时存放当前路径
	temp_array.push_back(root->data);
	vector< vector<int> > array;//保存每条路径的结点值
	array.push_back(temp_array);
	queue<node*> q;
	q.push(root);
	while (!q.empty())//bfs
	{
		node* top = q.front();
		q.pop();
		temp_array = array[0];
		if (top->lchild == NULL && top->rchild == NULL)
		{
			int sum = 0;
			for (int i = 0;i < temp_array.size();i++)
			{
				sum += temp_array[i];
			}
			if (sum == number)
			{
				ret.push_back(temp_array);
			}
		}
		if (top->lchild)
		{
			q.push(top->lchild);
			vector<int> temp(temp_array);
			temp.push_back(top->lchild->data);
			array.push_back(temp);
		}
		if (top->rchild)
		{
			q.push(top->rchild);
			vector<int> temp(temp_array);
			temp.push_back(top->rchild->data);
			array.push_back(temp);
		}
		vector< vector<int> >::iterator it = array.begin();
		array.erase(it);//将当前不完整的路径删除
	}
	return ret;
}

//************************************
// Method:    dfs
// FullName:  dfs
// Access:    public 
// Returns:   void
// Qualifier:
// Parameter: vector< vector<int> > & res 结果集
// Parameter: vector<int> & temp_array 临时存放访问路径
// Parameter: node * root 当前结点
// Parameter: int target 目标值
// Parameter: int sum 当前路径结点的和
//************************************
void dfs(vector< vector<int> >& res, vector<int>& temp_array, node* root, int target, int sum) {

	/*if (target < sum)
	{
		return;
	}*/
	temp_array.push_back(root->data);
	if (root->lchild == NULL && root->rchild == NULL && target == sum)
	{
		res.push_back(temp_array);
	}
	if (root->lchild)
	{
		dfs(res, temp_array, root->lchild, target, sum + root->lchild->data);
	}
	if (root->rchild)
	{
		dfs(res, temp_array, root->rchild, target, sum + root->rchild->data);
	}
	if (!temp_array.empty())
	{
		temp_array.pop_back();
	}
}

//二叉树中和为某一值的路径
vector< vector<int> > find_path_part(node* root, int target) {
	vector< vector<int> > res;//返回结果集
	vector<int> temp_array;//临时存放路径
	if (root == NULL)
	{
		return res;
	}
	dfs(res, temp_array, root, target, root->data);
	return res;
}

//二叉查找树的查找
void search_node(node* root, int x) {
	if (root == NULL)
	{
		cout << "查找失败!" << endl;
		return;
	}
	if (root->data == x)
	{
		cout << root->data << endl;
	}
	else if (root->data < x)
	{
		search_node(root->rchild, x);//查找右子树
	}
	else
	{
		search_node(root->lchild, x);//查找左子树
	}
}

//寻找最大值
node* find_max(node* root) {
	while (root->rchild)
	{
		root = root->rchild;//不断往右,直到没有右孩子
	}
	return root;
}
//寻找最小值
node* find_min(node* root) {
	while (root->lchild)
	{
		root = root->lchild;
	}
	return root;
}

//删除结点
void delete_node(node* &root, int x) {
	if (root == NULL)
	{
		return;
	}
	if (root->data == x)//找到删除的结点
	{
		if (root->lchild == NULL && root->rchild == NULL)
		{
			root = NULL;
		}else if (root->lchild)
		{
			node* pre = find_max(root->lchild);//找到前驱
			root->data = pre->data;
			delete_node(root->lchild, pre->data);//在左子树中删除结点
		}
		else if (root->rchild)
		{
			node* next_node = find_min(root->rchild);//找到后继
			root->data = next_node->data;
			delete_node(root->rchild, next_node->data);//在右子树中删除结点
		}
	}else if (root->data < x)
	{
		delete_node(root->rchild,x);//在右子树中删除
	}
	else
	{
		delete_node(root->lchild, x);//在左子树中删除
	}
}

//结点插入
void insert_node(node*& root, int data) {
	if (root == NULL)//此时需要插入
	{
		root = new node;
		root->data = data;
		root->lchild = root->rchild = NULL;
		return;
	}
	if (data < root->data)
	{
		insert_node(root->lchild, data);
	}
	else
	{
		insert_node(root->rchild, data);
	}
}

//先序遍历然后将结果存入v
void pre_order(node* root, vector<int> &v) {

	if (root == NULL)
	{
		return;
	}
	v.push_back(root->data);
	pre_order(root->lchild, v);
	pre_order(root->rchild, v);
}

//后序遍历然后将结果存入v
void post_order(node* root, vector<int> &v) {
	if (root == NULL)
	{
		return;
	}
	post_order(root->lchild, v);
	post_order(root->rchild, v);
	v.push_back(root->data);
}

//镜像树前序遍历,然后将结果存入v中
void pre_order_mirror(node* root, vector<int> &v) {
	if (root == NULL)
	{
		return;
	}
	v.push_back(root->data);
	pre_order_mirror(root->rchild, v);
	pre_order_mirror(root->lchild, v);
}

//镜像树后序遍历,然后将结果存入v中
void post_order_mirror(node* root, vector<int> &v) {
	if (root == NULL)
	{
		return;
	}
	post_order_mirror(root->rchild, v);
	post_order_mirror(root->lchild, v);
	v.push_back(root->data);
}


int main() {
	
	/*int vin_arr[] = { 1,2,3,4,5,6,7 };
	int post_arr[] = { 2,3,1,5,7,6,4 };
	vector<int> vin,post;
	for (int i = 0; i < 7; i++)
	{
		vin.push_back(vin_arr[i]);
		post.push_back(post_arr[i]);
	}
	node* root = create(vin, post);
	bfs(root);*/
	vector<int> origin, pre, preM, post, postM;
	int n, data;
	cin >> n;
	node* root = NULL;
	for (int i = 0;i < n; i++)
	{
		cin >> data;
		origin.push_back(data);
		insert_node(root, data);//构造二叉树
	}

	//求出各个序列
	pre_order(root, pre);
	pre_order_mirror(root, preM);
	post_order(root, post);
	post_order_mirror(root, postM);
	if (origin == pre)//初始序列等于先序
	{
		cout << "YES" << endl;
		for (int i = 0;i < post.size(); i++)
		{
			cout << post[i];
			if (i < post.size() - 1)
			{
				cout << " ";
			}
		}
	}else if (origin == preM)//初始序列等于镜像先序
	{
		cout << "YES" << endl;
		for (int i = 0;i < postM.size(); i++)
		{
			cout << postM[i];
			if (i < postM.size() - 1)
			{
				cout << " ";
			}
		}
	}
	else
	{
		cout << "No" << endl;
	}

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