二叉搜尋樹所具有的性質:
每個節點都有一個作為搜尋依據的關鍵碼(key),所有節點的關鍵碼互不相同。
左子樹上所有節點的關鍵碼(key)都小于根節點的關鍵碼(key)。
右子樹上所有節點的關鍵碼(key)都大于根節點的關鍵碼(key)。
每一個左右子樹都必須是二叉搜尋樹。
二叉搜尋樹的插入規則:
#include <iostream>
using namespace std;
template<class K,class V>
struct BSTreeNode
{
BSTreeNode<K, V>* _left;
BSTreeNode<K, V>* _right;
K _key;
V _value;
BSTreeNode(const K& key, const V& value)
:_left(NULL)
, _right(NULL)
, _key(key)
, _value(value)
{}
};
template<class K,class V>
class BSTree
{
typedef BSTreeNode<K, V> Node;
public:
BSTree()
:_root(NULL)
{}
bool Insert(const K& key, const V& value)
{
return _Insert(_root,key, value);
}
bool Find(const K& key)
{
return _Find(_root, key);
}
bool Remove(const K& key)
{
return _Remove(_root,key);
}
void InOrder()
{
_InOrder(_root);
}
~BSTree()
{}
protected:
bool _Insert(Node*& root, const K& key, const V& value)
{
if (root == NULL)
{
root = new Node(key, value);
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
{
cout << "已經存在該節點" << endl;
return false;
}
}
if (parent->_key < key)
parent->_right = new Node(key, value);
else if (parent->_key>key)
parent->_left = new Node(key, value);
return true;
}
bool _Find(Node* root, const K& key)
{
if (root == NULL)
return false;
Node* cur = root;
while (cur)
{
if (cur->_key == key)
return true;
else if (cur->_key > key)
cur = cur->_left;
else
cur = cur->_right;
}
cout <<key<<"該節點不存在" << endl;
return false;
}
bool _Remove(Node*& root, const K& key)
{
if (root == NULL)
return false;
Node* cur = root;
Node* del = NULL;
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
{
//1.左子樹為空
if (cur->_left == NULL)
{
del = cur;
if (parent == NULL || cur==root)
{
root = cur->_right;
}
else
{
if (parent->_left == cur)
parent->_left = cur->_right;
else if (parent->_right==cur)
parent->_right = cur->_right;
}
}
else if (cur->_right == NULL)//右子樹為空
{
del = cur;
if (parent == NULL || cur == root)
{
root = cur->_left;
}
else
{
if (parent->_left == cur)
parent->_left = cur->_left;
else
parent->_right = cur->_left;
}
}
else //左右都不為空
{
Node* left = cur->_left;
while (left->_right)//找它的左子樹上最右節點進行替換删除
{
parent = left;
left = left->_right;
}
swap(cur->_key, left->_key);
swap(cur->_value, left->_value);
del = left;
if (parent->_left == left)
parent->_left = NULL;
else
parent->_right = NULL;
}
delete del;
del = NULL;
cout << key << "删除成功" << endl;
return true;
break;
}
}
}
void _InOrder(Node* root)
{
if (root == NULL)
return;
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
protected:
Node* _root;
};
void Test()
{
BSTree<int, int> bt;
int a[] = { 6, 5, 2, 8, 3, 9, 0, 1, 4, 10, 7 };
for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
{
bt.Insert(a[i], i);
}
bt.InOrder();
cout << endl;
//cout << "節點是否存在?" << bt.Find(9) << endl;
//cout << "節點是否存在?" << bt.Find(6) << endl;
cout << "節點是否存在?" << bt.Find(1) << endl;
cout << "節點是否存在?" << bt.Find(10) << endl;
bt.Remove(5);
bt.Remove(6);
bt.Remove(1);
bt.Remove(10);
cout << "節點是否存在?" << bt.Find(1) << endl;
cout << "節點是否存在?" << bt.Find(10) << endl;
bt.InOrder();
}