- 每個節點都有一個作爲搜索依據的關鍵碼(key),所有節點的關鍵碼互不相同。
- 左子樹上所有節點的關鍵碼(key)都小於根節點的關鍵碼(key)。
- 右子樹上所有節點的關鍵碼(key)都大於根節點的關鍵碼(key)。
- 左右子樹都是二叉搜索樹。
#include<iostream>
#include<string>
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)
{}
//非遞歸插入
bool Insert(const K& key, const V& value)
{
if (_root == NULL)
{
_root = new Node(key, value);
return true;
}
Node* parent = NULL;
Node* cur = _root;
while (cur)
{
if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else
{
return false;
}
}
if (parent->_key < key)
parent->_right = new Node(key, value);
else
parent->_left = new Node(key, value);
return true;
}
//遞歸插入
bool InsertR(const K& key, const V& value)
{
return _InsertR(_root, key, value);
}
bool _InsertR(Node*& root, const K& key, const V& value)
{
if (root == NULL)
{
root = new Node(key, value);
return true;
}
if (root->_key > key)
return _InsertR(root->_left, key, value);
else if (root->_key < key)
return _InsertR(root->_right, key, value);
else
return false;
}
Node* Find(const K& key)
{
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;
}
Node* FindR(const K& key)
{
return _FindR(key);
}
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 Remove(const K& key)
{
Node* parent = NULL;
Node* cur = _root;
//cur不爲空
while (cur)
{
if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else
{
break;//相等時直接break掉
}
}
//cur爲空時,沒有找到指定刪除的節點,返回false
if (cur == NULL)
{
return false;
}
//cur的左子樹爲空
if (cur->_left == NULL)
{
//parent==NULL,說明cur是根節點,要刪除cur(由上步可知cur的左子樹爲空),所以要刪除cur,只需要讓_root指向cur->right即可。
if (parent == NULL)
{
_root = cur->_right;
}
else
{
if (parent->_left == cur)
parent->_left = cur->_right;
else
parent->_right = cur->_right;
}
delete cur;
}
else if (cur->_right == NULL)
{
if (parent == NULL)
{
_root = cur->_left;
}
else
{
if (parent->_left == cur)
parent->_left = cur->_left;
else
parent->_right = cur->_left;
}
delete cur;
}
else
{
// 找右子樹裏面的最左結點
parent = cur;
Node* subLeft = cur->_right;
while (subLeft->_left)
{
parent = subLeft;
subLeft = subLeft->_left;
}
cur->_key = subLeft->_key;
cur->_value = subLeft->_value;
if (parent->_left == subLeft)
parent->_left = subLeft->_right;
else
parent->_right = subLeft->_right;
delete subLeft;
}
return true;
}
//遞歸刪除
bool RemoveR(const K& key)
{
return _RemoveR(_root, key);
}
bool _RemoveR(Node*& root, const K& key)
{
if (root == NULL)
return false;
if (root->_key > key)
{
return _RemoveR(root->_left, key);
}
else if (root->_key < key)
{
return _RemoveR(root->_right, key);
}
else
{
if (root->_left == NULL)
{
root = root->_right;
}
else if (root->_right == NULL)
{
root = root->_left;
}
else
{
}
}
return true;
}
//中序遍歷
void InOrder()
{
_InOrder(_root);
cout << endl;
}
void _InOrder(Node* root)
{
if (root == NULL)
return;
}
protected:
Node* _root;
};
void TestTree()
{
BSTree<int, int> t;
int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
{
t.Insert(a[i], i);
}
t.InOrder();
cout << "IsBlance?" << t.IsBlanceTree() << endl;
t.Remove(8);
t.Remove(7);
t.Remove(2);
t.Remove(1);
t.InOrder();
t.Remove(0);
t.Remove(1);
t.Remove(2);
t.Remove(3);
t.Remove(4);
t.Remove(5);
t.Remove(6);
t.Remove(7);
t.Remove(8);
t.Remove(9);
t.InOrder();
}
void TestDict()
{
BSTree<string, string> dict;
dict.Insert("Tree", "樹");
dict.Insert("Sort", "哈希");
dict.Insert("Hash", "排序");
dict.InOrder();
BSTreeNode<string, string>* ret = dict.Find("Sort");
ret->_value = "排序";
ret = dict.Find("Hash");
ret->_value = "哈希";
dict.InOrder();
}