1 Star 0 Fork 1

ARMCSKGT/C和C++代码仓库

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
二叉搜索树.hpp 12.80 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
#include <iostream>
using namespace std;
namespace BST
{
template<class T>
struct TreeNode
{
T _key;
TreeNode<T>* _left;
TreeNode<T>* _right;
TreeNode()
:_key(T())
, _left(nullptr)
, _right(nullptr)
{}
TreeNode(const T& key)
:_key(key)
, _left(nullptr)
, _right(nullptr)
{}
};
template<class T>
struct Compare
{
bool operator()(const T& left, const T& right) { return left > right; }
};
//二叉搜索树
template<class T, class Com = Compare<T>>
class BSTree
{
using NodeType = TreeNode<T>;
using TreeType = BSTree<T, Com>;
public:
BSTree()
:_root(nullptr)
, _size(0)
{}
BSTree(const TreeType& bst)
:_root(nullptr)
, _size(0)
{
_root = Copy(bst._root);
_size = bst._size;
}
TreeType& operator=(TreeType bst)
{
swap(bst); //我们自己实现的交换函数
return *this;
}
bool Insert(const T& key)
{
if (_root == nullptr)
{
NodeType* newnode = new NodeType(key);
_root = newnode;
_size = 1;
return true;
}
NodeType* parent = _root;
NodeType* cur = _root;
while (cur)
{
parent = cur;
//节点值小于key
if (_com(key, cur->_key)) cur = cur->_right;
//节点值大于key
else if (_com(cur->_key, key)) cur = cur->_left;
else return false;
}
NodeType* newnode = new NodeType(key);
if (_com(key, parent->_key)) parent->_right = newnode;
else parent->_left = newnode;
++_size;
return true;
}
bool Erase(const T& key)
{
if (_root == nullptr) return false;
//删除节点
NodeType* parent = nullptr;
NodeType* cur = _root;
//找节点
while (cur)
{
//节点值小于key
if (_com(key, cur->_key))
{
parent = cur;
cur = cur->_right;
}
//节点值大于key
else if (_com(cur->_key, key))
{
parent = cur;
cur = cur->_left;
}
else //找到了 开始删除
{
if (cur->_right == nullptr) //删除的节点只有左子树
{
NodeType* DelNode = cur;
//改变链接关系
//如果要删除的是根节点
if (cur == _root) _root = cur->_left;
else //非根节点
{
if (parent->_left == cur) parent->_left = cur->_left;
else parent->_right = cur->_left;
}
delete DelNode;
}
else if (cur->_left == nullptr) //删除的节点只有右子树
{
NodeType* DelNode = cur;
//改变链接关系
//如果要删除的是根节点
if (cur == _root) _root = cur->_right;
else //非根节点
{
if (parent->_left == cur) parent->_left = cur->_right;
else parent->_right = cur->_right;
}
delete DelNode;
}
else //子节点都在
{
//找替代 左子树的最大节点(最右节点) 右子树的最小节点(最左节点)
//去左子树中找最大节点
//NodeType* maxParent = cur;
//NodeType* maxLeft = cur->_left;
//while (maxLeft->_right)
//{
// maxParent = maxLeft;
// maxLeft = maxLeft->_right;
//}
//cur->_key = maxLeft->_key;
////接管替代节点的右孩子
//if (maxParent->_left == maxLeft) maxParent->_left = maxLeft->_left;
//else maxParent->_right = maxLeft->_left;
//delete maxLeft;
//去右子树中找最小节点
NodeType* minParent = cur;
NodeType* minRight = cur->_right;
while (minRight->_left)
{
minParent = minRight;
minRight = minRight->_left;
}
cur->_key = minRight->_key;
//接管替代节点的右孩子
if (minParent->_left == minRight) minParent->_left = minRight->_right;
else minParent->_right = minRight->_right;
delete minRight;
}
--_size;
return true;
}
}
return false; //找不到节点
}
bool Find(const T& key) //key模型
{
if (_root == nullptr) return false;
NodeType* cur = _root;
while (cur)
{
if (_com(key, cur->_key)) cur = cur->_right;
else if (_com(cur->_key, key)) cur = cur->_left;
else return true;
}
return false;
}
bool RecuInsert(const T& key) //递归插入
{
return _RecuInsert(key, _root);
}
bool RecuErase(const T& key) //递归删除
{
return _RecuErase(key, _root);
}
bool RecuFind(const T& key)
{
return _RecuFind(key, _root);
}
size_t size() { return _size; }
void swap(TreeType& bst) //交换函数
{
//也可以调用库中的swap
NodeType* root = bst._root;
bst._root = _root;
_root = root;
Com com = bst._com;
bst._com = _com;
_com = com;
size_t sz = bst._size;
bst._size = _size;
_size = sz;
}
void clear() //清空节点
{
Destroy(_root);
_root = nullptr;
}
//中序遍历打印
void MidBfd()
{
_MidBfd(_root);
cout << endl;
}
~BSTree()
{
Destroy(_root);
_root = nullptr;
}
private:
//前序拷贝一棵树
NodeType* Copy(const NodeType* root)
{
if (root == nullptr) return nullptr;
NodeType* newnode = new NodeType(root->_key);
newnode->_left = Copy(root->_left);
newnode->_right = Copy(root->_right);
return newnode;
}
//中序
void _MidBfd(NodeType* root)
{
if (root == nullptr) return;
_MidBfd(root->_left);
cout << root->_key << " ";
_MidBfd(root->_right);
}
//后序销毁
void Destroy(NodeType* root)
{
if (root == nullptr) return;
Destroy(root->_left);
Destroy(root->_right);
delete root;
}
bool _RecuInsert(const T& key, NodeType*& root) //递归插入
{
if (root == nullptr)
{
NodeType* newnode = new NodeType(key);
root = newnode;
return true;
}
if (_com(key, root->_key)) return _RecuInsert(key, root->_right);
else if (_com(root->_key, key)) return _RecuInsert(key, root->_left);
return false;
}
bool _RecuErase(const T& key, NodeType*& root) //递归删除
{
if (root == nullptr) return false;
if (_com(key, root->_key)) return _RecuErase(key, root->_right);
else if (_com(root->_key, key)) return _RecuErase(key, root->_left);
else //找到了
{
NodeType* delNode = root;
if (root->_left == nullptr) root = root->_right;
else if (root->_right == nullptr) root = root->_left;
else //两个子节点都存在
{
//找一个替代
//找左边的最大节点
NodeType* cur = root->_left;
while (cur->_right) cur = cur->_right;
//找右边的最小节点
//NodeType* cur = root->_right;
//while (cur->_left) cur = cur->_left;
//将要删除的值与替代节点交换
T tmp = root->_key;
root->_key = cur->_key;
cur->_key = tmp;
return _RecuErase(key, root->_left); //转而删除子节点
//return _RecuErase(key, root->_right); //转而删除子节点
}
delete delNode;
return true;
}
return false;
}
bool _RecuFind(const T& key, NodeType* root)
{
if (root == nullptr) return false;
if (_com(key, root->_key)) return _RecuFind(key, root->_right);
else if (_com(root->_key, key)) return _RecuFind(key, root->_left);
else return true;
return false;
}
private:
NodeType* _root; //根节点
size_t _size; //节点数量
Com _com; //比较函数
};
//二叉搜索树KV
template<class KT,class VT , class Com = Compare<KT>>
class KVBSTree
{
using NodeType = TreeNode<pair<KT,VT>>;
using TreeType = KVBSTree<KT, VT, Com>;
public:
KVBSTree()
:_root(nullptr)
, _size(0)
{}
KVBSTree(const TreeType& bst)
:_root(nullptr)
, _size(0)
{
_root = Copy(bst._root);
_size = bst._size;
}
TreeType& operator=(TreeType bst)
{
swap(bst); //我们自己实现的交换函数
return *this;
}
bool Insert(const KT& key,const VT& value)
{
if (_root == nullptr)
{
NodeType* newnode = new NodeType({key,value});
_root = newnode;
_size = 1;
return true;
}
NodeType* parent = _root;
NodeType* cur = _root;
while (cur)
{
parent = cur;
//节点值小于key
if (_com(key, cur->_key.first)) cur = cur->_right;
//节点值大于key
else if (_com(cur->_key.first, key)) cur = cur->_left;
else return false;
}
NodeType* newnode = new NodeType({ key,value });
if (_com(key, parent->_key.first)) parent->_right = newnode;
else parent->_left = newnode;
++_size;
return true;
}
bool Erase(const KT& key)
{
if (_root == nullptr) return false;
//删除节点
NodeType* parent = nullptr;
NodeType* cur = _root;
//找节点
while (cur)
{
//节点值小于key
if (_com(key, cur->_key.first))
{
parent = cur;
cur = cur->_right;
}
//节点值大于key
else if (_com(cur->_key.first, key))
{
parent = cur;
cur = cur->_left;
}
else //找到了 开始删除
{
if (cur->_right == nullptr) //删除的节点只有左子树
{
NodeType* DelNode = cur;
//改变链接关系
//如果要删除的是根节点
if (cur == _root) _root = cur->_left;
else //非根节点
{
if (parent->_left == cur) parent->_left = cur->_left;
else parent->_right = cur->_left;
}
delete DelNode;
}
else if (cur->_left == nullptr) //删除的节点只有右子树
{
NodeType* DelNode = cur;
//改变链接关系
//如果要删除的是根节点
if (cur == _root) _root = cur->_right;
else //非根节点
{
if (parent->_left == cur) parent->_left = cur->_right;
else parent->_right = cur->_right;
}
delete DelNode;
}
else //子节点都在
{
//找替代 左子树的最大节点(最右节点) 右子树的最小节点(最左节点)
//去左子树中找最大节点
//NodeType* maxParent = cur;
//NodeType* maxLeft = cur->_left;
//while (maxLeft->_right)
//{
// maxParent = maxLeft;
// maxLeft = maxLeft->_right;
//}
//cur->_key = maxLeft->_key;
////接管替代节点的右孩子
//if (maxParent->_left == maxLeft) maxParent->_left = maxLeft->_left;
//else maxParent->_right = maxLeft->_left;
//delete maxLeft;
//去右子树中找最小节点
NodeType* minParent = cur;
NodeType* minRight = cur->_right;
while (minRight->_left)
{
minParent = minRight;
minRight = minRight->_left;
}
cur->_key = minRight->_key;
//接管替代节点的右孩子
if (minParent->_left == minRight) minParent->_left = minRight->_right;
else minParent->_right = minRight->_right;
delete minRight;
}
--_size;
return true;
}
}
return false; //找不到节点
}
pair<pair<KT,VT>,bool> Find(const KT& key) //key-value模型 通过key找value
{
//这里使用pair再套一层pair,用于返回查询的结果是否有效
//false表示查询返回值无效
if (_root == nullptr) return { {},false };
NodeType* cur = _root;
while (cur)
{
if (_com(key, cur->_key.first)) cur = cur->_right;
else if (_com(cur->_key.first, key)) cur = cur->_left;
else return { cur->_key,true };
}
return { {},false };
}
size_t size() { return _size; }
void swap(TreeType& bst) //交换函数
{
//也可以调用库中的swap
NodeType* root = bst._root;
bst._root = _root;
_root = root;
Com com = bst._com;
bst._com = _com;
_com = com;
size_t sz = bst._size;
bst._size = _size;
_size = sz;
}
void clear() //清空节点
{
Destroy(_root);
_root = nullptr;
}
//中序遍历打印
void MidBfd()
{
_MidBfd(_root);
cout << endl;
}
~KVBSTree()
{
Destroy(_root);
_root = nullptr;
}
private:
//前序拷贝一棵树
NodeType* Copy(const NodeType* root)
{
if (root == nullptr) return nullptr;
NodeType* newnode = new NodeType(root->_key);
newnode->_left = Copy(root->_left);
newnode->_right = Copy(root->_right);
return newnode;
}
//中序
void _MidBfd(NodeType* root)
{
if (root == nullptr) return;
_MidBfd(root->_left);
cout << root->_key.first << " : " << root->_key.second << endl;
_MidBfd(root->_right);
}
//后序销毁
void Destroy(NodeType* root)
{
if (root == nullptr) return;
Destroy(root->_left);
Destroy(root->_right);
delete root;
}
private:
NodeType* _root; //根节点
size_t _size; //节点数量
Com _com; //比较函数
};
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/armcskgt/c-and---c-code-warehouse.git
git@gitee.com:armcskgt/c-and---c-code-warehouse.git
armcskgt
c-and---c-code-warehouse
C和C++代码仓库
master

搜索帮助

D67c1975 1850385 1daf7b77 1850385