二叉搜索树的性质:
- 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。
- 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。
- 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。
- 左右子树都是二叉搜索树。
非递归
bool insert(const T& key)
bool Insert(const T& key)
{
if (_root == NULL)
{
_root = new Node(key);
return true;
}
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
return false;
}
cur = new Node(key);
if (parent->_key > cur->_key)
{
parent->_left = cur;
}
else
parent->_right = cur;
return true;
}
Remove(const K& key)
先找到key所在结点,找到了删除,没找到return false;
删除时遇到的几种情况:
- 叶子结点,直接删
- 只有一个孩子的非叶子结点
- 其他结点
怎么删?
- 叶子结点直接删除
- 不是叶子结点,怎么删?
cur左为空(也可删叶子结点):
(让parent和cur不为空的孩子(右孩子)连起来)
注意cur是根结点的情况(parent ==NULL)
判断cur是parent 的左还是右,parent->_left(_right) = cur->_right;
cur右为空
(让parent和cur不为空的孩子(左孩子)连起来)
注意cur是根结点的情况(parent ==NULL)
判断cur是parent 的左还是右,parent->_left(_right) = cur->_left;
cur左右都不为空
找替代结点(和Key大小最接近的两个结点之一都可以),左树的最右结点(小的里面找最大的)或 ,右树的最左结点(大的里的最小的)。
找替代结点时要记录替代结点的parent,找到替代结点后, cur->_key= sub ->_key,
然后删除替代结点,(让parent和替代结点不为空的孩子(右孩子)连起来)
若在左树中找最右(最大)则替代结点的右为NULL,左不一定为NULL;
若在右树中找最左(最小)则替代结点的左为NULL,右不一定为NULL;
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//找到要删的结点了
{
Node* del = cur;
if (cur->_left == NULL )//左为空
{
if (cur == _root)
{
_root = cur->_right;
}
else if (parent->_left == cur)
parent->_left = cur->_right;
else
parent->_right = cur->_right;
}
else if (cur->_right == NULL )//右为空
{
if (cur == _root)
{
_root = cur->_left;
}
else if (parent->_left == cur)
parent->_left = cur->_left;
else
parent->_right = cur->_left;
}
else//左右都不为空
{
Node* parent = cur;
Node* sub = cur->_right;
while (sub->_left)
{
parent = sub;
sub = sub->_left;
}
cur->_key = sub->_key;
parent->_left = sub->_right;
del = sub;
}
delete del;
return true;
}
}
}
Node* Find(const T& key)
Node* Find(const T& key)
{
if (_root == NULL)
{
cout << "没找到" << key << endl;
return NULL;
}
Node* cur = _root;
while (cur)
{
if (cur->_key < key)
{
cur = cur->_right;
}
else if (cur->_key > key)
{
cur = cur->_left;
}
else
{
cout << "找到"<<key<<"了" << endl;
return cur;
}
}
cout << "没找到" << key << endl;
return NULL;
}
递归
bool insertR(const K& key)
bool _insertR(Node* &root,const K& key)
{
if(root == NULL)
{
root = new Node(key);
return true;
}
if(root->_key > key)
return _insertR(root->left,key);
else if(root->key < key)
return _insert(root->right,key);
else
return false;
}
bool insertR(const K& key)
{
return _insertR(_root,key);
}
Node* FindR(const K& key)
Node* _FindR(Node* &root, const T& key)
{
if (root == NULL)
{
cout << "没找到" << key << endl;
return NULL;
}
if (root->_key < key)
_FindR(root->_right, key);
else if (root->_key > key)
_FindR(root->_left, key);
else
{
cout << "找到" << key << "了" << endl;
return root;
}
}
Node* FindR(const T& key)
{
return _FindR(_root, key);
}
bool RemoveR(const K& key)
bool _RemoveR(Node* &root,const K& key)
{
if(root == NULL)
{
return false;
}
else if (root ->key >key)
{
return _RemoveR(root->left,key);
}
else if(root->key < key)
{
return _RemoveR(root->right,key);
}
else
{
Node* del = root;
if(root->left == NULL)
root = root->right;
else if(root->right == NULL)
root = root ->left;
else
{
Node* sub = root->right;
while(sub->left){
sub = sub->left;
}
root->key = sub->key;
return _RemoveR(root->right,sub->key);
}
delete del;
return ture;
}
}