12 二叉搜索树的操作

#include <iostream>
#include <vector>

using namespace std;

typedef struct Tree {
	int key;
	Tree *left;
	Tree *right;
	Tree *parent;
}Tree;
//必须对root为引用或者指向指针操作,涉及到改变root本身地址问题 
void TreeInsert(Tree *&root, Tree *&z)
{
	//cout << z->key << endl;
	//Tree *x, *y;
	Tree *y = NULL;
	Tree *x = root;
	//if(root == NULL)
	//	cout << "not root\n";
	while(x != NULL)
	{
		//cout << "while x=>" << x->key << "*" << endl;
		y = x;
		//cout << "while y=>" << y->key << "*" << endl;
		if(z->key < x->key)
			x = x->left;
		else
			x = x->right;
		//if(x == NULL)
		//	cout << "**" <<endl;
		
	}
	//cout << "--\n";
	//z->left = NULL;
	//z->right = NULL;
	z->parent = y;
	//if(z->parent == NULL)
	//{
	//	cout << "not zp" << endl;
	//}
	//cout << "zp" << z->parent->key << endl; 
	if(y == NULL)
	{
		//root = new Tree;
		//root->left = NULL;
		//root->right = NULL;
		//root->parent = NULL;
		//root->key = z->key;
		//此处为root指向z的地址,root本身地址发生改变 
		root = z;
		//cout << "root " << root->key <<endl;
	} 
	else if(z->key < y->key)
	{
		y->left = z;
		//cout << "y->left " << y->left->key << " y "<< y->key << endl; 
	} 
	else
	{
		y->right = z;
		//cout << "y->right " << y->right->key << " y " << y->key << endl;
	}
	//cout << y->key << endl; 
}

void createSerachTree(Tree *&root, vector<int> nums)
{
	//Tree *z = new Tree;
	for(vector<int>::iterator it = nums.begin(); it != nums.end(); it ++)
	{
		Tree *z = new Tree;//每次创建一个 
		z->key = *it; 
		//此处必须每次初始化z,否则insert函数改变z的操作保留,
		//因此可能会出现死循环 
		z->left = NULL;
		z->right = NULL;
		z->parent = NULL;
		//cout << "Z->"<< z->key << endl;
		TreeInsert(root, z);
		//delete z; //不能释放z空间,否则最后创建的结点为空(即整个树夫人结点边创建边释放)
	}
	//delete z;
}

Tree *TreeMinimum(Tree *x)
{
	while(x->left != NULL)
	{
		x = x->left;
	}
	return x;
}

Tree *TreeMaximum(Tree *x)
{
	while(x != NULL)
		x = x->right;
	return x;
}

Tree *TreePredecesor(Tree *x)
{
	Tree *y;
	if(x->left != NULL)
		return TreeMaximum(x->left);
	y = x->parent;
	while(y != NULL && x == y->left)
	{
		x = y;
		y = y->parent;
	}
	return y;
}

Tree *TreeSuccessor(Tree *x)
{
	Tree *y;
	if(x->right != NULL)
		return TreeMinimum(x->right);
	y = x->parent;
	while(y != NULL && x == y->right)
	{
		x = y;
		y = y->parent;
	}
	return y;
}

//垃圾回收不能在此函数,因为在该函数外涉及到要删元素的地址指向 
void TransPlant(Tree *&root, Tree *&u, Tree*&v)
{
	//Tree *tmp;
	if(u->parent == NULL)
	{
		//delete root;
		//tmp = root;
		//tmp = v;
		root = v;
		//cout << root->key << " tmp " << tmp->key << endl;
		//delete tmp;	
		//tmp = NULL;
	}	
	else if(u == u->parent->left)
	{
		//delete u->parent->left;
		//tmp = u->parent->left;
		//tmp = v;
		u->parent->left = v;
		//cout << u->parent->left->key << " tmp " << tmp->key << endl;
		//delete tmp;
		//tmp = NULL;
	}
	else
	{
		//delete u->parent->right;
		//tmp = u->parent->right;
		//tmp = v;
		u->parent->right = v;
		//cout << u->parent->right->key << " tmp " << tmp->key << endl;
		//delete tmp;
		//tmp = NULL;
	}
} 

void TreeDelete(Tree *&root, Tree *&z)
{
	Tree *tmp1, *tmp2; //暂存要删元素的地址 
	if(z->left == NULL)
	{
		tmp1 = z;
		TransPlant(root, z, z->right);
		delete tmp1;
	}
	else if(z->right == NULL)
	{
		tmp1 = z;
		TransPlant(root, z, z->left);
		delete tmp1;
	}
	else
	{
		Tree *y; //y为z的右子树的最小结点,即z的后继
		y = TreeMinimum(z->right);
		if(y->parent != z) //y不是z的右子树
		{
			tmp2 = y;
			TransPlant(root, y, y->right);
			y->right = z->right;//此处涉及被删元素y的地址指向操作 
			y->right->parent = y;  
			delete tmp2;
		} 
		tmp1 = z;
		TransPlant(root, z, y);
		y->left = z->left; //此处涉及被删元素z的地址指向操作
		y->left->parent = y;
		delete tmp1;
	}
}

Tree *TreeSearch(Tree *x, int key) //树的起始结点 
{
	/* 递归查找 
	if(x == NULL || key == x->key)
	{
		return x;
	}
	if(key < x->key)
	{
		return TreeSearch(x->left, key);
	}
	else
	{
		return TreeSearch(x->right, key);
	}
	*/ 
	//非递归
	while(x != NULL && key != x->key)
	{
		if(key < x->key)
			x = x->left;
		else
			x = x->right;	
	} 
	return x;
}

void InOderShow(Tree *root)
{
	if(root != NULL)
	{
		InOderShow(root->left);
		cout << "T " << root->key << endl;
		InOderShow(root->right);
	}
	
}
int main()
{
	Tree *root, *z, *y;// = new Tree();
	root = NULL;
	vector<int> nums{12, 5, 18, 2, 9, 15, 19, 13, 17};
	createSerachTree(root, nums);
	z = TreeSearch(root, 13);
	TreeDelete(root, z);
	z = TreeSearch(root, 9);
	y = TreePredecesor(z);
	cout << "前驱 " << y->key << endl;
	z = TreeSearch(root, 9);
	y = TreeSuccessor(z);
	cout << "后继 " << y->key << endl;
	cout << "树根 " << root->key << endl; 
	InOderShow(root);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值