二叉搜索树的性质:
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>