二叉搜索树

二叉搜索树中最复杂的操作:删除一个节点
1.删除二叉搜索树中的最小节点:一直向左子树遍历,直到遍历到某个节点的左子树为空时,说明该节点就是整个二叉搜索树的最小节点。如果该节点还有右子树,直接把右子树放到应被删除的节点上就可以了。
2.删除二叉搜索树中的最大节点:一直向右子树遍历,直到遍历到某个节点的右子树为空时,说明该节点就是整个二叉搜索树的最大节点。如果该节点还有左子树,直接把左子树放到应被删除的节点上就可以了。
3.如果要删除的节点只有一个孩子,或左子树或右子树,那么操作都是简单的,和上面类似。
4.删除任意节点(既有左孩子又有右孩子):用该节点右子树中的最小节点(也就是该节点的后继节点)替换要删除的节点即可。为什么?因为该节点的右子树中任意节点都一定是比左子树大的,同时又为了满足二叉搜索树右子树的节点大于当前结点的性质,选取要删除节点右子树中的最小节点替换该节点即可。
当然,使用前驱节点(左子树中的最大节点)代替要删除的节点也是可以的!

template<typename Key, typename Value>
class BST
{
private:
	struct Node
	{
		Key key;
		Value value;
		Node *left;
		Node *right;
	};
	Node(Key key, Value value)
	{
		this->key = key;
		this->value = value;
		this->left = this->right = NULL;
	}
	Node *root;
	int count;
public:
	BST()
	{
		root = NULL;
		count = 0;
	}
	~BST()
	{
		destroy(root);
	}
	int size()
	{
		return count;
	}
	bool isempty()
	{
		return count == 0;
	}
	void insert(Key key, Value value)
	{
		root = insert(root, key, value);
	}
	bool contain(Key key)
	{
		return contain(root, key);
	}
	Value*  search(Key key)
	{
		return search(root, key);
	}
	void destroy(Node* node)
	{
		if (node != NULL)
		{
			destroy(node->left);
			destroy(node->right);
			delete node;
			count--;
		}
	}
	Key minimum()
	{
		assert(count != 0);
		Node* minNode = minimum(root);
		return minNode->key;
	}
	Key maximum()
	{
		assert(count != 0);
		Node* maxNode = maximum(root);
		return maxNode->key;
	}
	void removeMin()
	{
		if (root)
			root = removeMin(root);
	}
	void remove(Key key)
	{
		root = remove(root, key);
	}
private:
	//向node为根的二叉搜索树中插入(key,value),返回插入新节点后的二叉搜索树的根
	Node* insert(Node *node, Key key, Value value)
	{
		if (node == NULL)
		{
			count++;
			return new Node(key, value);  
		}
		if (key == node->key)
			node->value = value;
		else if (key < node->key)
			node->left = insert(node->left, key, value);
		else
			node->right = insert(node->right, key, value);
		return node;
	}
	bool contain(Node* node, Key key)
	{
		if (node == NULL)
			return false;
		if (node->key == key)
			return true;
		else if (key < node->key)
			return contain(node->left, key);
		else
			return contain(node->right, key);
	}
	//在以node为根的二叉搜索树中查找key所对应的value
	Value* search(Node* node, Key key)
	{
		if (node == NULL)
			return NULL;
		if (key == node->key)
			return &(node->value);
		else if (key < node->key)
			return search(node->left, key);
		else
			return search(node->right, key);
	}
	Node* minimum(Node* node)
	{
		if (node->left == NULL)
			return node;
		return minimum(node->left);
	}
	Node* maximum(Node* node)
	{
		if (node->right == NULL)
			return node;
		return maximum(node->right);
	}
	//删掉以node为根的二分搜索树中的最小节点,返回删除后新的二分搜索树的根
	Node* removeMin(Node* node)
	{
		if (node->left == NULL)
		{
			Node* rightNode = node->right;
			delete node;
			count--;
			return rightNode;
		}
		node->left = removeMin(node->left);
		return node;
	}
	Node* remove(Node* node, Key key)
	{
		if (node == NULL)
			return NULL;
		if (key < node->key)
		{
			node->left = remove(node->left, key);
			return node;
		}
		else if (key > node->key)
		{
			node->right = remove(node->right, key);
			return node;
		}
		else//key == node->key
		{
			if (node->left == NULL)
			{
				Node* rightNode = node->right;
				delete node;
				count--;
				return rightNode;
			}
			if (node->right == NULL)
			{
				Node* leftNode = node->left;
				delete node;
				count--;
				return leftNode;
			}
			//node->left!=NULL && node->right!=NULL
			Node *successor = new Node(minimum(node->right));
			successor->left = removeMin(node->right);
			successor->left = node->left;
			delete node;
			count--;
			return successor;
		}
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值