二叉查找树

二叉查找树的实现

二叉查找树性质
  • 任意节点其左子树上任意值比节点值 小 右子树上任意值比节点值 大
  • 插入 大于当前节点向右子树 小于向左
  • 删除 当删除节点 具有左右子树 找到左子树最大值(最右边)与其交换删除 / 找到右子树最小值(最左边) 交换删除 满足查找树性质
  • 删除 当删除节点 **只有一边有子树时 将第一个子节点与其交换 **
template<class T>
struct TreeNode {
	T val;
	TreeNode<T> *left;
	TreeNode<T> *right;
	TreeNode(T x) : val(x), left(nullptr), right(nullptr) {};
};
//二叉查找树
template<class T>
class FindTree
{
	TreeNode<T>* root;
public:
	FindTree() { root = nullptr; };
	~FindTree() {};

public:
	void Insert(T value);
	void Delete(TreeNode<T>* node);
	TreeNode<T>* Find(TreeNode<T>* node);
private:

};
//插入
template<class T>
void FindTree<T>::Insert(T value)
{
	TreeNode<T>* push = new TreeNode<T>(value);
	if (root == nullptr)
		root = new TreeNode<T>(value);
	else
	{
		TreeNode<T>* temp = root;
		while (temp!=nullptr)
		{
			if (push->val == temp->val)
			{
				return;
			}
				
			if (push->val > temp->val)
			{
				if (temp->right == nullptr)
				{
					temp->right = push;
					break;
				}	
				else
					temp = temp->right;
			}
			else if (push->val < temp->val)
			{
				if (temp->left == nullptr)
				{
					temp->left = push;
					break;
				}
				else
					temp = temp->left;
			}
				
		}
	}
}
template<class T>
void FindTree<T>::Delete(TreeNode<T> * node)
{
	if (node == nullptr||root==nullptr)
		return;
	//找到删除的父节点和 删除节点
	TreeNode<T>* parent = nullptr, *reNode = root;
	while (reNode != nullptr)
	{
		if (node->val == reNode->val)
			break;
		else if (node->val > reNode->val)
		{
			parent = reNode;
			reNode = reNode->right;
		}
		else
		{
			parent = reNode;
			reNode = reNode->left;
		}
	}
	//如果存在删除节点
	if (reNode != nullptr)
	{
		
		//具备左右节点 选择左子树中最大的/选择右子树最小的 此次选左子树最大
		if (reNode->left != nullptr && reNode->right != nullptr)
		{

			TreeNode<T>* node1 = reNode, *node2 = reNode->left;
			while (node2->right != nullptr)
			{
				node1 = node2;
				node2 = node2->right;
			}
			//要删除的节点和左子树最大节点交换
			reNode->val = node2->val;

			if (parent->left == reNode)
				parent->left = node2;
			else if (parent->right == reNode)
				parent->right = node2;

			delete node2;
			node2 = nullptr;
		}
		else if (reNode->left == nullptr)//只有右子树 选择第一个右节点
		{
			if (reNode == root)
			{
				root = root->right;
				return;
			}
			if (parent->left == reNode)
				parent->left = reNode->right;
			else
				parent->right = reNode->right;
			delete reNode;
			reNode == nullptr;
		}
		else if(reNode->right==nullptr)//只有左子树 选择第一个左节点
		{
			if (reNode == root)
			{
				root = root->left;
				return;
			}
			if (parent->left == reNode)
				parent->left = reNode->left;
			else
				parent->right = reNode->left;
			delete reNode;
			reNode = nullptr;
		}
	}


}
template<class T>
TreeNode<T>* FindTree<T>::Find(TreeNode<T> * node)
{
	if (node == nullptr||root==nullptr)
		return nullptr;
	TreeNode<T>* temp=root;
	while (temp!=nullptr)
	{
		if (temp->val == node->val)
			return temp;
		else if(node->val > temp->val)
		{
			temp = temp->right;
		}
		else
		{
			temp = temp->left;
		}
	}
	return nullptr;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值