目录
二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
它的左右子树也分别为二叉搜索树
- #pragma once
- #include
- #include
- using namespace std;
-
- template<class K>
- struct BSTreeNode
- {
- BSTreeNode
* _left; - BSTreeNode
* _right; - K _key;
-
- BSTreeNode(const K& key)
- :_left(nullptr)
- , _right(nullptr)
- , _key(key)
- {}
-
- };
-
-
- template<class K>
- class BSTree
- {
- typedef BSTreeNode
Node; - private:
- Node* _root = nullptr;
-
- Node* _CopyTree(const Node* root)
- {
- if (root == nullptr)
- {
- return nullptr;
- }
-
- Node* copyNode = new Node(root->_key);
- copyNode->_left = _CopyTree(root->_left);
- copyNode->_right = _CopyTree(root->_right);
-
- return copyNode;
- }
-
- void _DestroyTree(Node* root)
- {
- if (root == nullptr)
- return;
-
- _DestroyTree(root->_left);
- _DestroyTree(root->_right);
- delete root;
-
- }
-
- void _InOrder(Node* root)
- {
- if (root == nullptr)
- return;
-
- _InOrder(root->_left);
- cout << root->_key<<" ";
- _InOrder(root->_right);
-
- }
- public:
- BSTree() = default;
-
- BSTree(const BSTree
& t) - {
- _root = _CopyTree(t._root);
- }
-
- BSTree
& operator=(BSTree t) - {
- swap(_root, t._root);
-
- return *this;
- }
-
- ~BSTree()
- {
- _DestroyTree(_root);
- _root = nullptr;
- }
-
- bool Insert(const K& key)
- {
- if (_root == nullptr)
- {
- _root = new Node(key);
- return true;
- }
-
- Node* parent = nullptr;
- 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;
- }
- }
-
- cur = new Node(key);
- if (parent->_key < key)
- {
- parent->_right = cur;
- }
- else
- {
- parent->_left = cur;
- }
-
- return true;
- }
-
- bool Find(const K& key)
- {
- if (_root == nullptr)
- {
- return false;
- }
-
- Node* cur = _root;
- while (cur)
- {
- if (cur->_key < key)
- {
- cur = cur->_right;
- }
- else if (cur->_key < key)
- {
- cur = cur->_left;
- }
- else
- {
- return true;
- }
- }
-
- return false;
- }
-
- bool Erase(const K& key)
- {
- Node* parent = nullptr;
- 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//找到了
- {
- if (cur->_left == nullptr)//左孩子为空
- {
- if (cur == _root)//删根
- {
- _root = cur->_right;
- }
- else
- {
- if (parent->_left == cur)
- {
- parent->_left = cur->_right;
- }
- else
- {
- parent->_right = cur->_right;
- }
- }
- delete cur;
- }
- else if (cur->_right == nullptr)//右孩子为空
- {
- if (cur == _root)//删根
- {
- _root = cur->_left;
- }
- else
- {
- if (parent->_left == cur)
- {
- parent->_left = cur->_left;
- }
- else
- {
- parent->_right = cur->_left;
- }
- }
- delete cur;
-
- }
- else//两边都不为空,找左子树最大或者右子树最小
- {
- //这里用右子树最小
- Node* minParent = cur;
- Node* minRight = cur->_right;
- while (minRight->_left)
- {
- minParent = minRight;
- minRight = minRight->_left;
- }
- //换值
- swap(cur->_key, minRight->_key);
-
- if (minParent->_left == minRight)
- {
- minParent->_left = minRight->_right;
- }
- else//只会在删头的时候出现
- {
- minParent->_left = 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:
- bool _FindR(Node* root, const K& key)
- {
- if (root == nullptr)
- return;
-
- if (root->_key < key)
- {
- _FindR(root->_right, key);
- }
- else if (root->_key > key)
- {
- _FindR(root->_left, key);
- }
- else
- {
- return true;
- }
- }
-
- bool _InsertR(Node*& root, const K& key)
- {
- if (root == nullptr)
- {
- root = new Node(key);
- return true;
- }
-
- if (root->_key < key)
- {
- _InsertR(root->_right, key);
- }
- else if (root->_key > key)
- {
- _InsertR(root->_left, key);
- }
- else
- {
- return false;
- }
- }
-
- bool _EraseR(Node*& root, const K& key)
- {
- if (root == nullptr)
- return false;
-
- if (root->_key < key)
- {
- _EraseR(root->_right, key);
- }
- else if (root->_key > key)
- {
- _EraseR(root->_left, key);
- }
- else
- {
- Node* del = root;
- if (del->_left == nullptr)
- {
- root = del->_right;
- }
- else if (del->_right == nullptr)
- {
- root = del->_left;
- }
- else
- {
- Node* minRight = root->_right;
- while (minRight->_left)
- {
- minRight = minRight->_left;
- }
- swap(root->_key, minRight->_key);
- return _EraseR(root->_right, key);
- }
- delete del;
- return true;
- }
- }
- };
其中带R的为递归实现
1. K模型:K模型即只有key作为关键码,结构中只需要存储Key即可,关键码即为需要搜索到
的值。
比如:
给一个单词word,判断该单词是否拼写正确,具体方式如下:
以词库中所有单词集合中的每个单词作为key,构建一棵二叉搜索树在二叉搜索树中检索该单词是否存在,存在则拼写正确,不存在则拼写错误。
小区车辆的门禁、宿舍门禁、教学楼门禁都是这种情景
2. KV模型:每一个关键码key,都有与之对应的值Value,即
比如:
英汉词典中英文与中文的对应关系,通过英文可以快速找到与其对应的中文,英文单词与其对应的中文
再比如统计单词次数,统计成功后,给定单词就可快速找到其出现的次数,单词与其出
现次数就是