二叉查找树(BinarySearch Tree,也叫二叉搜索树,或称二叉排序树Binary Sort Tree)或者是一棵空树,或具有如下性质:
- 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。
- 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。
- 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。
- 左右子树都是二叉搜索树。
二叉搜索树相关操作:
(1)插入:新节点
在二叉查找树中插入新结点,要保证插入新结点后仍能满足二叉查找树的性质。插入过程如下:
a、若二叉查找树root为空,则使新结点为根;
b、若二叉查找树root不为空,则查找该节点应插入的位置。若新结点的关键字小于插入点的关键字,则将新结点插入到插入点的左子树中,大于则插入到插入点的右子树中。否则,不插入,返回失败。
(2)查找:关键码的节点
a.从根节点开始查找,若关键字小于目前节点的关键字,则到目前节点的左子树中查询;若关键字大于目前节点的关键字,则到目前节点的右子树中查询;否则,查找成功,返回当前节点。
b.若到空还没找到,则查找失败。
(3)、删除
删除某个结点后依然要保持二叉查找树的特性。删除过程如下:
a、若删除点是叶子结点,则设置其双亲结点的对应指针为空。
b、若删除点只有左子树,或只有右子树,则设置其双亲结点的指针指向左子树或右子树。
c、若删除点的左右子树均不为空,则:采用替代删除法
1)查询删除点的右子树中的非空最小节点(即最左节点),交换要删除节点与右最小节点的关键码与值,删除右最小节点。
或
#include<iostream>
using namespace std;
//搜索二叉树
template<class K,class V>
struct BSTreeNode
{
K _key;
V _val;
BSTreeNode<K,V>* _left;
BSTreeNode<K,V>* _right;
BSTreeNode(K& key,V& val)
:_key(key)
, _val(val)
, _left(NULL)
, _right(NULL)
{}
};
template<class K,class V>
class BSTree
{
typedef BSTreeNode<K, V> Node;
public:
BSTree()
:_root(NULL)
{}
~BSTree()
{
_Destroy(_root);
_root = NULL;
}
bool Insert(K& key, V& val)
{
if (_root == NULL)
{
_root = new Node(key, val);
return true;
}
else
{
Node* parent = NULL;
Node* cur = _root;
while (cur)
{
if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else
{
return false;
}
}
cur = new Node(key, val);
if (parent->_key < key)
{
parent->_right = cur;
}
else
{
parent->_left = cur;
}
return true;
}
}
Node* Find(const K& key)
{
if (_root == NULL)
return NULL;
Node* cur = _root;
while (cur)
{
if (cur->_key < key)
cur = cur->_right;
else if (cur->_key>key)
cur = cur->_left;
else
return cur;
}
return NULL;
}
bool Remove(const K& 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 = NULL;
if (cur->_left == NULL)
{
del = cur;
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)
{
del = cur;
if (cur == _root)
{
_root = cur->_left;
}
else
{
if (parent->_left == cur)
{
parent->_left = cur->_left;
}
else
{
parent->_right = cur->_left;
}
}
}
else//左右都不为空
{
Node* rightMin = cur->_right;
parent = cur;
while (rightMin->_left)
{
parent = rightMin;
rightMin = rightMin->_left;
}
cur->_key = rightMin->_key;
cur->_val = rightMin->_val;
del=rightMin;
if (parent->_left == rightMin)
parent->_left = NULL;
else
parent->_right = NULL;
}
delete del;
return true;
}
}
return false;
}
void InOrder()
{
if (_root == NULL)
return;
_InOrder(_root);
cout << endl;
}
bool InsertR(K& key, V& val)
{
return _InsertR(_root, key, val);
}
Node* FindR(const K& key)
{
return _FindR(_root, key);
}
bool RemoveR(K key)
{
return _RemoveR(_root, key);
}
protected:
void _Destroy(Node* root)
{
if (root == NULL)
return;
_Destroy(root->_left);
_Destroy(root->_right);
delete root;
}
bool _InsertR(Node*& root, K& key, V& val)
{
if (root == NULL)
{
root = new Node(key, val);
return true;
}
if (root->_key > key)
return _InsertR(root->_left, key, val);
else if (root->_key < key)
return _InsertR(root->_right, key, val);
else
return false;
}
Node* _FindR(Node* root, const K& key)
{
if (root == NULL)
return NULL;
if (root->_key < key)
return _FindR(root->_right, key);
else if (root->_key>key)
return _FindR(root->_left, key);
else
return root;
}
bool _RemoveR(Node*& root, K& key)
{
if (root == NULL)
return false;
if (root->_key < key)
return _RemoveR(root->_right, key);
else if (root->_key>key)
return _RemoveR(root->_left, key);
else
{
Node* del = root;
if (root->_left == NULL)
{
root = root->_right;
}
else if (root->_right == NULL)
{
root = root->_left;
}
else
{
Node* rightMin = root->_right;
Node* parent = root;
while (rightMin->_left)
{
parent = rightMin;
rightMin = rightMin->_left;
}
root->_key = rightMin->_key;
root->_val = rightMin->_val;
del = rightMin;
if (parent->_left == rightMin)
parent->_left = NULL;
else
parent->_right = NULL;
}
delete del;
return true;
}
}
protected:
void _InOrder(Node* root)
{
if (root == NULL)
return;
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
private:
Node* _root;
};
void Test1()
{
int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
BSTree<int, int> t;
for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
{
t.Insert(a[i], i);
}
for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
{
cout<<"是否存在"<<a[i]<<" "<<t.Find(a[i])->_key<<endl;
}
t.InOrder();
cout << 5 << t.Remove(5) << endl;
cout << 8 << t.Remove(8) << endl;
cout << 2 << t.Remove(2) << endl;
cout << 1 << t.Remove(1) << endl;
cout << 3 << t.Remove(3) << endl;
cout << 7 << t.Remove(7) << endl;
t.InOrder();
}
void Test2()
{
int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
BSTree<int, int> t;
for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
{
t.InsertR(a[i], i);
}
for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
{
cout << "是否存在" << a[i] << " " << t.FindR(a[i])->_key << endl;
}
t.InOrder();
cout << 5 << t.RemoveR(5) << endl;
cout << 8 << t.RemoveR(8) << endl;
cout << 2 << t.RemoveR(2) << endl;
cout << 1 << t.RemoveR(1) << endl;
cout << 3 << t.RemoveR(3) << endl;
cout << 7 << t.RemoveR(7) << endl;
cout << 9 << t.RemoveR(9) << endl;
cout << 0 << t.RemoveR(0) << endl;
cout << 4 << t.RemoveR(4) << endl;
cout << 6 << t.RemoveR(6) << endl;
cout << 5 << t.RemoveR(5) << endl;
cout << 6 << t.RemoveR(6) << endl;
t.InOrder();
}
#include"SBTree.h"
int main()
{
//Test1();
Test2();
system("pause");
return 0;
}