BSTree ---- 二叉搜索树
二叉搜索树的性质:
- 每个结点都有一个作为搜索依据的关键码(key),所有结点的关键码互不相同。
- 左子树上所有结点的关键码(key)都小于根结点的关键码(key)。
- 右子树上所有结点的关键码(key)都大于根结点的关键码(key)。
- 左右子树都是二叉搜索树。
故中序遍历这棵树它的key是按
升序排列
的
- 二叉搜索树的插入
插入结点时,比当前结点小就往左树走,比当前结点大,就往右树走,直到为空就可以插入。
- 二叉搜索树的查找
查找与插入类似,查找的这个结点比当前结点小,就往左走,比当前结点大,就往右走,与当前结点相同就代表找到了,如果左右都为空则代表没找到。
- 二叉搜索树的删除
删除要分为3种情况
左为空
- 删除的为根结点的话,直接让根为根的右孩子。
- 若parent的左为cur,则parent的左孩子为cur的左孩子,若parent的右为cur,则parent的右孩子cur的右孩子。
右为空
- 删除的为根结点的话,直接让根为根的左孩子。
- 若parent的左为cur,则parent的左孩子为cur的左孩子,若parent的右为cur,则parent的右孩子cur的右孩子。
左右都不为空
这时我们用
替换法删除
找左子树的最右结点或者右子树的最左结点,替换删除即可。(以替换最右子树的最左结点为例)
情况一:
情况二:
扫描二维码关注公众号,回复:
1014031 查看本文章
完整代码
template<class K> struct BinarySearchTree { BinarySearchTree* _left; BinarySearchTree* _right; K _key; BinarySearchTree(const K& key) :_left(NULL) , _right(NULL) , _key(key) {} }; template<class K> class BSTree { typedef BinarySearchTree<K> Node; public: BSTree() :_root(NULL) {} bool Insert(const K& key)//插入 { if (_root == NULL) { _root = new Node(key); } Node* cur = _root; Node* parent = NULL; 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); if (parent->_key > key) { parent->_left = cur; } else { parent->_right = cur; } return true; } bool InsertR(const K& key)//递归插入 { return _InsertR(_root, key); } bool _InsertR(Node*& root,const K& key) { if (root == NULL) { root = new Node(key); return true; } if (root->_key > key) { return _InsertR(root->_left, key); } else if (root->_key < key) { return _InsertR(root->_right, key); } else { return false; } } Node* Find(const K& key) { if (_root == NULL) { return NULL; } Node* cur = _root; while (cur) { if (cur->_key > key) { cur = cur->_left; } else if (cur->_key < key) { cur = cur->_right; } else { return cur; } } return NULL; } Node* FindR(const K& key)//递归查找 { return _FindR(_root, key); } Node* _FindR(Node* root, const K& key) { if (root == NULL) { return NULL; } if (root->_key > key) { return _FindR(root->_left, key); } else if (root->_key < key) { return _FindR(root->_right, key); } else { return root; } } bool Remove(const K& key) { 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 { //删除 //1.左为空 //2.右为空 //3.左右都不为空 Node* del = cur; if(cur->_left == NULL) //左为空 { 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) //右为空 { if (parent == NULL) //若删除的为根节点,则单独处理 { _root = cur->_left; } else { if (parent->_left == cur) { parent->_left = cur->_left; } else { parent->_right = cur->_left; } } } else //左右都不为空 { //替换法删除 Node* parent = cur; Node* sub = cur->_right; while (sub->_left)//找最左结点 { parent = sub; sub = sub->_left; } cur->_key = sub->_key; if (cur->_key == parent->_key) { parent->_right = sub->_right; } else { parent->_left = sub->_right; } delete sub; } return true; } } return false; } 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) { _RemoveR(root->_left, key); } else if (root->_key < key) { _RemoveR(root->_right, key); } else { Node* del = root; if (root->_left == NULL) { root = root->_right; } else if (root->_right == NULL) { root = root->_left; } else { Node* sub = root->_right; while (sub->_left) { sub = sub->_left; } swap(root->_key, sub->_key); _RemoveR(root->_right, key); } delete del; del = NULL; } return true; } 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; }; //测试 void TestBSTree() { int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 }; BSTree<int> t; for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i) { //t.Insert(a[i]); t.InsertR(a[i]); } t.InOrder(); //cout << t.Find(5) << endl; // 测试情况 // 1. 左为空/右为空 // 2. 左右都不为空 t.Remove(8); t.Remove(2); t.Remove(1); t.Remove(5); 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(); //// 相不到情况 /*t.RemoveR(0); t.RemoveR(1); t.RemoveR(2); t.RemoveR(3); t.RemoveR(4); t.RemoveR(5); t.RemoveR(6); t.RemoveR(7); t.RemoveR(9); t.InOrder();*/ }