一. 二叉搜索树的性质:
每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。
左子树上所有节点的关键码(key)都小于根节点的关键码(key)。
右子树上所有节点的关键码(key)都大于根节点的关键码(key)。
左右子树都是二叉搜索树。
二. 以下图为例
int a [] = {5,3,4,1,7,8,2,6,0,9};
三. 代码实现
#include<iostream>
using namespace std;
template<class K, class V>
struct BSTreeNode
{
K _key;
V _value;
BSTreeNode<K, V>* _left;
BSTreeNode<K, V>* _right;
BSTreeNode(const K& key, const V& value)
:_key(key)
, _value(value)
, _left(NULL)
, _right(NULL)
{}
};
template<class K, class V>
class BSTree
{
typedef BSTreeNode<K, V> Node;
public:
BSTree()
:_root(NULL)
{}
~BSTree()
{}
bool Insert(const K& key, const V& value)
{
Node* cur = _root;
Node* parent = cur;
if (_root == NULL)
{
_root = new Node(key, value);
return true;
}
while (cur)
{
if (key > cur->_key)
{
parent = cur;
cur = cur->_right;
}
else if (key < cur->_key)
{
parent = cur;
cur = cur->_left;
}
else
return false;
}
if (key > parent->_key)
{
parent->_right = new Node(key, value);
}
else
{
parent->_left = new Node(key, value);
}
return true;
}
Node* Find(const K& key)
{
if (_root == NULL)
return NULL;
Node* cur = _root;
while (cur)
{
if (key > cur->_key)
cur = cur->_right;
else if (key < cur->_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;
Node* del = NULL;
//find
while (cur)
{
if (key > cur->_key)
{
parent = cur;
cur = cur->_right;
}
else if (key < cur->_key)
{
parent = cur;
cur = cur->_left;
}
//delete
else
{
Node* del;
//要删的节点的左子树为空
if (cur->_left == NULL)
{
del = cur;
//root
if (parent == NULL)
_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 (parent == NULL)
_root = cur->_left;
else
{
if (parent->_left = cur)
parent->_left = cur->_left;
else
parent->_right = cur->_left;
}
//return true;
}
//要删的节点的左右子树都不为空
else
{
parent = cur;
//找右子树的最左节点或找左子树的最右节点
Node* tmp = cur->_right;//tmp不能用引用
while (tmp->_left)
{
parent = tmp;
tmp = tmp->_left;
}
cur->_key = tmp->_key;
cur->_value = tmp->_value;
del = tmp;
//把tmp的子树连接在tmp的parent上
if (parent->_left == tmp)
parent->_left = tmp->_right;
else
parent->_right = tmp->_right;
}
delete del;
return true;
}
}
return false;
}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
void _InOrder(Node*& root)
{
if (root == NULL)
return;
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
protected:
Node* _root;
};
int main()
{
int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
BSTree<int, int> bst;
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
{
bst.Insert(a[i], i);
}
bst.InOrder();
//BSTreeNode<int,int>* node = bst.Find(5);
//cout << node->_key << endl;
//bst.Find(100);
cout << bst.Remove(13) << endl;
bst.InOrder();
cout << bst.Remove(5) << endl;
bst.InOrder();
bst.Remove(7);
bst.InOrder();
bst.Remove(8);
bst.InOrder();
bst.Remove(9);
bst.InOrder();
bst.Remove(0);
bst.Remove(1);
bst.Remove(2);
bst.Remove(3);
bst.Remove(4);
bst.Remove(5);
bst.Remove(6);
bst.Remove(7);
bst.Remove(8);
bst.Remove(9);
bst.InOrder();
system("pause");
return 0;
}四. 二叉搜索树的缺陷
可能变成单链表,而失去当它搜索时每次都能排除一半节点的特性。解决办法是把树变得平衡。
本文出自 “sunshine225” 博客,请务必保留此出处http://10707460.blog.51cto.com/10697460/1826944
原文:http://10707460.blog.51cto.com/10697460/1826944