二叉查找树(BinarySearch Tree,也叫二叉搜索树,或称二叉排序树Binary Sort Tree)或者是一棵空树,或具有如下性质:
- 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。
- 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。
- 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。
- 左右子树都是二叉搜索树。
二叉搜索树相关操作:
(1)插入:新节点
在二叉查找树中插入新结点,要保证插入新结点后仍能满足二叉查找树的性质。插入过程如下:
a、若二叉查找树root为空,则使新结点为根;
b、若二叉查找树root不为空,则查找该节点应插入的位置。若新结点的关键字小于插入点的关键字,则将新结点插入到插入点的左子树中,大于则插入到插入点的右子树中。否则,不插入,返回失败。
(2)查找:关键码的节点
a.从根节点开始查找,若关键字小于目前节点的关键字,则到目前节点的左子树中查询;若关键字大于目前节点的关键字,则到目前节点的右子树中查询;否则,查找成功,返回当前节点。
b.若到空还没找到,则查找失败。
(3)、删除
删除某个结点后依然要保持二叉查找树的特性。删除过程如下:
a、若删除点是叶子结点,则设置其双亲结点的对应指针为空。
b、若删除点只有左子树,或只有右子树,则设置其双亲结点的指针指向左子树或右子树。
c、若删除点的左右子树均不为空,则:采用替代删除法
1)查询删除点的右子树中的非空最小节点(即最左节点),交换要删除节点与右最小节点的关键码与值,删除右最小节点。
或
2)查询删除点的左子树中的非空最大节点(即最右节点),交换要删除节点与左最大节点的关键码与值,删除左最大节点。
注:中序遍历二叉查找树可得到一个关键字的有序序列。
#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; }
注:搜索树的缺陷是一定情况下会退化为单链表。如果插入顺序为1,2,3。则树的插入,查找,删除复杂度皆为O(n).
时间: 2024-10-22 06:43:52