二叉搜索树

二叉搜索树的性质:

1. 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。

2. 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。

3. 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。

4. 左右子树都是二叉搜索树。

5.中序遍历的结果是有序的。

定义一个节点:

<span style="font-size:24px;"><span style="font-size:24px;">template<class T>
struct BSTreeNode
{
	BSTreeNode(const T& key)
		:_key(key)
		,_left(NULL)
		,_right(NULL)
	{}
	BSTreeNode<T>* _left;
	BSTreeNode<T>* _right;
	T _key;
};</span></span>
构树插入节点递归算法:

<span style="font-size:24px;">bool InsertR(const T& key)
	{
		return _InsertR(_root,key);
	}</span>
<span style="font-size:24px;">bool _InsertR(Node*& root,const T& key)
	{
		if(root==NULL)
		{
			root=new Node(key);
			return true;
		}
		if(root->_key>key)
		{
			_InsertR(root->_left ,key);
		}
		else if(root->_key <key)
		{
			_InsertR(root->_right ,key);
		}
		else  //这个数存在root->_key==key
		{
			return false;
		}

	}</span>
非递归:

<span style="font-size:24px;">bool Insert(const T& key)
	{
		//1.空树
		//2.不存在
		//3.存在
		
		//空树
		if(_root==NULL)
		{
			_root=new Node(key);
			return true;
		}
		Node* cur=_root;
		Node* prev=cur;
		while(cur)
		{
			if(cur->_key >key)
			{
				prev=cur;
				cur=cur->_left ;
			}
		    else if(cur->_key <key)
			{
				prev=cur;
				cur=cur->_right ;
			}
			else //if(cur->_key ==key)
				return false;  //存在
		}
		//不存在
		
		if(prev->_key >key)
		{
			cur=new Node(key);
		    prev->_left =cur;
		}
		else
		{
			cur=new Node(key);
		    prev->_right =cur;
		}
		return true;
	}</span>

我在这里分析一下删除一个节点的思路:


(1).当删5这个节点时,直接删除就可以。

(2).当删9这个节点时,9这个节点的特点是左指针为空,只需要让11这个节点指向10就可以。

(3).当删11这个节点时,11这个节点的特点是右指针为空,只需要让6这个节点指向10就可以。

(4).当删6这个节点时,找右子树的最左节点或左子树的最右节点,然后值交换,再删除找到的节点,这样它同样满足二叉搜索树的性质。

非递归:

<span style="font-size:24px;">bool Remove(const T& key)
	{
		if(_root==NULL)
			return false;
		Node* cur=_root;
		Node* parent=NULL;
		while(cur)
		{
			if(cur->_key <key)
			{
				parent=cur;
				cur=cur->_right ;
			}
				
			else if(cur->_key >key)
			{
				parent=cur;
				cur=cur->_left ;
			}
			else    //找到key,再删除
			{
				if(cur->_left==NULL )   //左为空
				{
					if(parent->_left ==cur)
					{
						parent->_left =cur->_right ;
						delete cur;
					    
					}
					else
					{
						parent->_right =cur->_right ;
						delete cur;
						
					}
				}
				else if(cur->_right ==NULL)  //右为空
				{
					if(parent->_left ==cur)
					{
						parent->_left =cur->_left ;
						delete cur;
						
					}
					else
					{
						parent->_right =cur->_left ;
						delete cur;
						
					}
				}
				else    //删除的节点左右都不为空
				{
					//找右子树的最左节点
					Node* rightree=cur->_right ;
					Node* prev=NULL;
					while(rightree->_left )
					{
						prev=rightree;
						rightree=rightree->_left ;
					}
					if(rightree->_right ==NULL)
					{
						cur->_key =rightree->_key ;
						delete rightree;
						prev->_left =NULL;
						
					}
					else
					{
						cur->_key =rightree->_key ;
						prev->_left =rightree->_right ;
						delete rightree;
						
					}
				}
				return true;
			}
		}
		return false;
	}</span>
查找比较简单我只实现了非递归的:

<span style="font-size:24px;">bool Find(const T& key)
	{
		Node* cur=_root;
		while(cur)
		{
			if(cur->_key <key)
			{
				cur=cur->_right ;
			}
			else if(cur->_key >key)
			{
				cur=cur->_left ;
			}
			else if(cur->_key ==key)
				return true;	
		}
		return false;
	}</span>
中序遍历它得到是有序的,我只实现了递归的,非递归的思想我在前面的博客中有实现二叉树的非递归遍历思想是一样的:
<span style="font-size:24px;">void InOrderR()
	{
		_InOrderR(_root);
		cout<<endl;
	}</span>
<span style="font-size:24px;">void _InOrderR(Node* root)
	{
		if(root==NULL)
		return;
	   _InOrderR(root->_left );
	   cout<<root->_key<<" " ;
	   _InOrderR(root->_right );
	}</span>




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值