一. 二叉搜索樹的性質:
每個節點都有一個作爲搜索依據的關鍵碼(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; }
四. 二叉搜索樹的缺陷
可能變成單鏈表,而失去當它搜索時每次都能排除一半節點的特性。解決辦法是把樹變得平衡。