二叉搜索树的实现(查找,插入,删除的递归与非递归)

本文详细介绍了二叉搜索树的基本概念、节点结构及其关键操作,包括查找、插入和删除节点的具体实现方法,并提供了非递归及递归两种实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BST定义:

二叉搜索树:又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树
1、若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
2、若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
3、它的左右子树也分别为二叉搜索树

除此之外,还有一点值得在意:二叉搜索树的最左节点是所有节点的值中最小值,而最右节点则是最大值。

BST的实现:

1.节点的定义:

template<class K,class V>
struct Node
{
	Node(const K& key,const V& value)
		:_key(key)
		,_value(value)
		,_pLeft(NULL)
		,_pRight(NULL)
	{}


	K _key;
	V _value;
	Node<K,V>* _pLeft;
	Node<K,V>* _pRight;
};
2.查找节点中指定key值的节点的实现

①非递归

Node* Find(const K& key)    //外部接口
{
	return _Find(_pRoot,key);
}

Node* _Find(Node* pRoot,const K& key)  //实现方法
{
	if(pRoot==NULL)
		return NULL;

	while(pRoot)
	{
		if(key<pRoot->_key)
		{
			pRoot=pRoot->_pLeft;
		}
		else if(key>pRoot->_key)
		{
			pRoot=pRoot->_pRight;
		}
		else
			return pRoot;
	}

	return NULL;
}

②非递归

Node* Find(const K& key)   //外部接口
{
	return _Find(_pRoot,key);
}

Node* _Find(Node* pRoot,const K& key)   //实现方法
{
	if(pRoot==NULL)
		return NULL;

	if(pRoot->_key==key)
		return pRoot;
	else if(key<pRoot->_key)
		return _Find(pRoot->_pLeft,key);
	else
		return _Find(pRoot->_pRight,key);
}


3.插入指定key值与value值的节点

由于在这里我们认为key值是区分这些节点的关键字,而且是不能重复的,所以有以下实现:

①非递归

bool Insert(const K& key, const V& value)   //外部接口
{
	return _Insert(_pRoot,key,value);
}

bool _Insert(Node*& pRoot,const K& key,const V& value)    //实现方法
{
	if(pRoot==NULL)
	{
		pRoot=new Node(key,value);
		return true;
	}

	Node* pcur=pRoot;
	Node* parent=NULL;
	while(pcur)
	{
		if(pcur->_key==key)
			return false;
		else if(key<pcur->_key)
		{
			parent=pcur;
			pcur=pcur->_pLeft;
		}
		else
		{
			parent=pcur;
			pcur=pcur->_pRight;
		}
	}

	pcur=new Node(key,value);
	if(key<parent->_key)
		parent->_pLeft=pcur;
	else
		parent->_pRight=pcur;

	return true;
}

②递归

bool Insert(const K& key, const V& value)   //外部接口
{
	return _Insert(_pRoot,key,value);
}

bool _Insert(Node*& pRoot,const K& key,const V& value)   //实现方法
{
	if(pRoot==NULL)
	{
		pRoot=new Node(key,value);
		return true;
	}

	if(pRoot->_key==key)
		return false;
	
	if(key<pRoot->_key)
		return _Insert(pRoot->_pLeft,key,value);
	else
		return _Insert(pRoot->_pRight,key,value);
}


4.删除指定key值的节点

对于删除这一操作,我们仔细分析一下当中节点可能的情况:

1.有右孩子无左孩子,且在双亲的右子树中


2.有右孩子无左孩子,且在双亲的左子树中


3.有右孩子无左孩子,且为根节点


4.有左孩子无右孩子,且在双亲的右子树中


5.有左孩子无右孩子,且在双亲的左子树中


6.有左孩子无右孩子,且为根节点


7.有左孩子有右孩子,且为根节点


8.有左孩子有右孩子,但不为根节点


①非递归

bool Remove(const K& key)    //外部接口
{
	return _Remove(_pRoot,key);
}


bool _Remove(Node*& pRoot,const K& key)     //实现方法
{
	if(pRoot==NULL)
		return false;

	Node* pcur=pRoot;
	Node* parent=NULL;
	while(pcur)
	{
		if(key<pcur->_key)
		{
			parent=pcur;
			pcur=pcur->_pLeft;
		}
		else if(key>pcur->_key)
		{
			parent=pcur;
			pcur=pcur->_pRight;
		}
		else
		{
			if(pcur->_pLeft==NULL)
			{
				if(pcur==pRoot)
					pRoot=pcur->_pRight;

				else if(pcur==parent->_pLeft)
					parent->_pLeft=pcur->_pRight;
				else
					parent->_pRight=pcur->_pRight;
			}
			else if(pcur->_pRight==NULL)
			{
				if(pcur==pRoot)
					pRoot=pcur->_pLeft;

				else if(pcur==parent->_pLeft)
					parent->_pLeft=pcur->_pLeft;
				else
					parent->_pRight=pcur->_pLeft;
			}
			else
			{
				Node* pDel=pcur;
				parent=pcur;
				pDel=pDel->_pRight;
				while(pDel->_pLeft)
				{
					parent=pDel;
					pDel=pDel->_pLeft;
				}
				pcur->_key=pDel->_key;
				pcur->_value=pDel->_value;

				if(pDel==parent->_pLeft)
				{
					parent->_pLeft=pDel->_pRight;
				}
				else
				{
					parent->_pLeft=pDel->_pRight;
				}

				pcur=pDel;
			}

			delete pcur;
			return true;
		}
	}

	return false;
}


②递归

bool Remove(const K& key)   //外部接口
{
	return _Remove(_pRoot,key);
}


bool _Remove(Node*& pRoot,const K& key)    //实现方法
{
	if(pRoot==NULL)
		return false;
	
	if(key<pRoot->_key)
		return _Remove(pRoot->_pLeft,key);
	else if(key>pRoot->_key)
		return _Remove(pRoot->_pRight,key);
	else
	{
		Node* pcur=pRoot;
		if(pcur->_pLeft==NULL)
		{
			pRoot=pcur->_pRight;
			delete pcur;
		}
		else if(pcur->_pRight==NULL)
		{
			pRoot=pcur->_pLeft;
			delete pcur;
		}
		else
		{
			Node* pDel=pRoot;
			pcur=pcur->_pRight;
			while(pcur->_pLeft)
			{
				pcur=pcur->_pLeft;
			}
			pDel->_key=pcur->_key;
			pDel->_value=pcur->_value;
			_Remove(pRoot->_pRight,pcur->_key);

		}
		return true;
	}
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值