目录
二叉搜索树又称二叉排序树,是一种特殊有序的二叉树。

①二叉搜索树的查找
②二叉搜索树的插入
③二叉搜索树的删除
- template <class K>//类模板
- struct BSTNode
- {
- BSTNode* left;
- BSTNode* right;
- K _key;
- BSTNode(K key)
- :left(nullptr)
- , right(nullptr)
- , _key(key)
- {}
- };
从根开始查找,如果要查找的值比根节点大就往右子树走,如果比根节点小就往左子树走,依次循环,直到找到或走到空,则结束。找到则返回true,找不到返回false。
- bool find(const K& key)
- {
- BSTNode
* cur = _root; - while (cur)
- {
- if (cur->_key == key)
- return true;
- else if (cur->_key < key)
- cur = cur->right;
- else
- cur = cur->left;
- }
- return false;
- }
思路和非递归是一样的,如果查找的节点为空表示该树中没有该节点,返回false,如果找到了就返回true
- bool _findR(BSTNode
* root, const K& key) - {
- if (!root)return false;
- if (root->_key == key)
- return true;
- else if (root->_key > key)
- return _findR(root->left, key);//往左子树走
- else
- return _findR(root->right, key);//往右子树走
- }
判断树是否为空,如果树为空的话,那么直接新增一个节点,并把该节点的地址赋给_root指针(指向根节点的指针)。如果树不为空,那么就按照二叉搜索树的查找方法,找到插入的位置,然后将新节点插入。注意:如果相等那么将返回false,不能插入
- bool insert(const K& key)
- {
- if (_root == nullptr)
- {
- _root= new BSTNode
(key); - return true;
- }
-
- BSTNode
* cur = _root, *parent=nullptr; - while (cur)
- {
- if (_root->_key < key)
- {
- parent = cur;
- cur = cur->right;
- }
- else if (_root->_key > key)
- {
- parent = cur;
- cur = cur->left;
- }
- else
- return false;
- }
-
- BSTNode
* newnode = new BSTNode(key); - if (parent->_key < key)
- { //插入的节点大于该插入位置的父节点,往右边插入
- parent->right = newnode;
- }
- else
- { //插入的节点小于该插入位置的父节点,往左边插入
- parent->left = newnode;
- }
- return true;
- }
这里传的是引用,形参的改变可以影响实参,所以直接给root赋值了
- bool _InsertR(BSTNode
*& root, const K& key) - { //如果根节点为空,直接把值赋给root
- if (!root)
- BSTNode
* root = new BSTNode(key); - if (root->_key > key)
- {
- return _InsertR(root->left, key);
- }
- else if (root->_key < key)
- {
- return _InsertR(root->right, key);
- }
- else
- return false;
-
- }
首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情
况:
看起来有待删除节点有4种情况,实际情况1可以与情况2或者3合并起来,因此真正的删除过程
如下:
- bool Erase(const K& key)
- {
- BSTNode
* cur = _root, * parent =nullptr; - while (cur)
- {
- if (cur->_key < key)
- {
- parent = cur;
- cur = cur->right;
- }
- else if (cur->_key > key)
- {
- parent = cur;
- cur = cur->left;
- }
- else
- { //没有左孩子节点
- if (cur->left == nullptr)
- {
- if (parent == nullptr)
- {
- _root = _root->right;
- }
- else if (parent->left == cur)
- {
- parent->left = cur->right;
- }
- else
- {
- parent->right = cur->right;
- }
- delete cur;
- }
- //没有右孩子节点
- else if (cur->right == nullptr)
- {
- if (parent == nullptr)
- {
- _root = _root->right;
- }
- else if (parent->left == cur)
- {
- parent->left = cur->left;
- }
- else
- {
- parent->right = cur->left;
- }
- delete cur;
- }
- //左右孩子都有的节点
- else
- {
- BSTNode
*minparent = cur; - BSTNode
* minright = cur->right; - while (minright->left)
- {
- minparent = minright;
- minright = minright->left;
- }
- swap(minright->_key, cur->_key);
- if (minparent->left = minright)
- {
- minparent->left = minright->right;
- }
- else
- {
- minparent->right = minright->right;
- }
- delete minright;
- }
- }
- return true;
- }
- return false;
-
- }
- bool _EraseR(BSTNode
*& root, const K& key)//传引用 - {
- if (!root)return false;
- if (root->_key == key)
- {
- BSTNode
* del = root; - // 删除
- if (root->left == nullptr)
- {
- root = root->right;
- }
- else if (root->right == nullptr)
- {
- root = root->left;
- }
- else
- {
- BSTNode
* minRight = root->right; - while (minRight->left)
- {
- minRight = minRight->left;
- }
-
- swap(root->_key, minRight->_key);
- //交换完以后继续递归删除
- return _EraseR(root->right, key);
- }
-
- delete del;
- return true;
- }
- else if (root->_key > key)
- return _EraseR(root->left, key);
- else
- return _EraseR(root->right, key);
- }
当创建好二叉搜索树后,我们需要知道自己的相关操作对不对,所以需要遍历二叉搜索树来验证,
那什么遍历方式好呢?这里选的是中序遍历,因为二叉搜索树左边都是小于根节点的,右边都是大于根节点的,所以使用中序遍历可以得到一个呈升序的序列
- void _Inorder(BSTNode
* root) - {
- if (!root)return;
- _Inorder(root->left);
- cout << root->_key << ' ';
- _Inorder(root->right);
- }
- //C++11支持的编译器强制生成默认构造函数
- //BST() = default;
- BST()//构造
- {}
-
- BSTNode
* CopyTree( BSTNode* root) - {
- if (root == nullptr)
- return nullptr;
-
- BSTNode
* copyNode = new BSTNode(root->_key); - copyNode->_left = CopyTree(root->_left);
- copyNode->_right = CopyTree(root->_right);
-
- return copyNode;
- }
- BST(const BST
& bst)//拷贝构造 - {
- _root = CopyTree(bst);
- }
-
- BST
& operator=(const BST bst)//赋值重载 - {
- swap(_root, bst._root);
- return *this;
- }
- #pragma once
- #include
- using namespace std;
-
- template <class K>
- struct BSTNode
- {
- BSTNode* left;
- BSTNode* right;
- K _key;
- BSTNode(K key)
- :left(nullptr)
- , right(nullptr)
- , _key(key)
- {}
- };
-
- template <class K>
- class BST
- {
- public:
- //C++11支持的编译器强制生成默认构造函数
- //BST() = default;
- BST()
- {}
-
- BSTNode
* CopyTree( BSTNode* root) - {
- if (root == nullptr)
- return nullptr;
-
- BSTNode
* copyNode = new BSTNode(root->_key); - copyNode->_left = CopyTree(root->_left);
- copyNode->_right = CopyTree(root->_right);
-
- return copyNode;
- }
- BST(const BST
& bst) - {
- _root = CopyTree(bst);
- }
-
- BST
& operator=(const BST bst) - {
- swap(_root, bst._root);
- return *this;
- }
-
- bool find(const K& key)
- {
- BSTNode
* cur = _root; - while (cur)
- {
- if (cur->_key == key)
- return true;
- else if (cur->_key < key)
- cur = cur->right;
- else
- cur = cur->left;
- }
- return false;
- }
-
-
- bool insert(const K& key)
- {
- if (_root == nullptr)
- {
- _root= new BSTNode
(key); - return true;
- }
- BSTNode
* cur = _root, *parent=nullptr; - while (cur)
- {
- if (_root->_key < key)
- {
- parent = cur;
- cur = cur->right;
- }
- else if (_root->_key > key)
- {
- parent = cur;
- cur = cur->left;
- }
- else
- return false;
- }
- BSTNode
* newnode = new BSTNode(key); - if (parent->_key < key)
- {
- parent->right = newnode;
- }
- else
- parent->left = newnode;
- return true;
- }
-
-
- bool Erase(const K& key)
- {
- BSTNode
* cur = _root, * parent =nullptr; - while (cur)
- {
- if (cur->_key < key)
- {
- parent = cur;
- cur = cur->right;
- }
- else if (cur->_key > key)
- {
- parent = cur;
- cur = cur->left;
- }
- else
- {
- if (cur->left == nullptr)
- {
- if (parent == nullptr)
- {
- _root = _root->right;
- }
- else if (parent->left == cur)
- {
- parent->left = cur->right;
- }
- else
- {
- parent->right = cur->right;
- }
- delete cur;
- }
- else if (cur->right == nullptr)
- {
- if (parent == nullptr)
- {
- _root = _root->right;
- }
- else if (parent->left == cur)
- {
- parent->left = cur->left;
- }
- else
- {
- parent->right = cur->left;
- }
- delete cur;
- }
- else
- {
- BSTNode
*minparent = cur; - BSTNode
* minright = cur->right; - while (minright->left)
- {
- minparent = minright;
- minright = minright->left;
- }
- swap(minright->_key, cur->_key);
- if (minparent->left = minright)
- {
- minparent->left = minright->right;
- }
- else
- {
- minparent->right = minright->right;
- }
- delete minright;
- }
- }
- return true;
- }
- return false;
-
- }
-
- void Inorder()
- {
- _Inorder(_root);
- cout << endl;
- }
- bool findR(const K& key)
- {
- return _findR(_root, key);
-
- }
-
- bool InsertR(const K& key)
- {
- return _InsertR(_root, key);
- }
- bool EraseR(const K& key)
- {
- return _EraseR(_root, key);
- }
-
- private:
- void _Inorder(BSTNode
* root) - {
- if (!root)return;
- _Inorder(root->left);
- cout << root->_key << ' ';
- _Inorder(root->right);
- }
- bool _findR(BSTNode
* root, const K& key) - {
- if (!root)return false;
- if (root->_key == key)
- return true;
- else if (root->_key > key)
- return _findR(root->left, key);
- else
- return _findR(root->right, key);
- }
-
- bool _InsertR(BSTNode
*& root, const K& key) - {
- if (!root)
- BSTNode
* root = new BSTNode(key); - if (root->_key > key)
- {
- return _InsertR(root->left, key);
- }
- else if (root->_key < key)
- {
- return _InsertR(root->right, key);
- }
- else
- return false;
-
- }
-
- bool _EraseR(BSTNode
*& root, const K& key) - {
- if (!root)return false;
- if (root->_key == key)
- {
- BSTNode
* del = root; - // 删除
- if (root->left == nullptr)
- {
- root = root->right;
- }
- else if (root->right == nullptr)
- {
- root = root->left;
- }
- else
- {
- BSTNode
* minRight = root->right; - while (minRight->left)
- {
- minRight = minRight->left;
- }
-
- swap(root->_key, minRight->_key);
-
- return _EraseR(root->right, key);
- }
-
- delete del;
- return true;
- }
- else if (root->_key > key)
- return _EraseR(root->left, key);
- else
- return _EraseR(root->right, key);
- }
-
- BSTNode
* _root = nullptr; - };
二叉搜索树的知识就分享到这里了,有什么错误还望指出。