二叉搜索树又叫二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树
//查找
Node* find(const T& val)
{
//从根节点开始查找
Node* cur = _root;
while (cur)
{
if (cur->_val == val)
return cur;
else if (cur->_val < val)
cur = cur->_right;
else
cur = cur->_left;
}
//不存在返回空
return nullptr;
}
//插入:1.空树(直接插入) 2.非空树(搜索+插入)还要判断数据是否存在
bool insert(const T& val)
{
//判断是否为空树
if (_root == nullptr)
{
_root = new Node(val);
return true;
}
//搜索插入的位置
Node* cur = _root;
Node* parent = nullptr;
while (cur)
{
parent = cur;
if (cur->_val == val)
return false;
else if (cur->_val < val)
cur = cur->_left;
else
cur = cur->_right;
}
//确定新插入数据的左右位置
cur = new Node(val);
if (parent->_val < val)
parent->_right = cur;
else
parent->_left = cur;
return true;
}
//删除
bool erase(const T& val)
{
//1.判断根节点
if (_root == nullptr)
return false;
Node* cur = _root;
Node* parent = nullptr;
//查找
while (cur)
{
if (cur->_val == val)
break;
else if (cur->_val < val)
{
parent = cur;//更新节点
cur = cur->_right;
}
else
{
parent = cur;
cur = cur->_left;
}
}
//判断cur是否为空
if (cur == nullptr)
return false;
//删除:叶子or非叶子?
//1.叶子节点
if (cur->_left == nullptr && cur->_right == nullptr)
{
//判断删除的是否为根节点
if (cur == _root)
{
_root = nullptr;
}
else
{
if (parent->_left == cur)
parent->_left == nullptr;
else
parent->_right == nullptr;
}
delete cur;
}
//2.非叶子节点
//左边为空,右边不为空
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
{
//左右孩子都存在
//1.找左子树最右节点
Node* child = cur->_left;
parent = cur;
while (child->_right)
{
parent = child;
child = child->_right;
}
//2.最右节点的值覆盖cur位置的值
cur->_val = child->_val;
//3.重新链接
if (parent->_left == child)
parent->_left = child->_left;
else
parent->_right = child->_left;
//4.删除最右节点
delete child;
}
return true;
}
#include
using namespace std;
template<class T>
struct Node
{
T _val;
Node* _left;
Node* _right;
Node(const T& val = T())
:_val(val)
,_left(nullptr)
,_right(nullptr)
{
}
};
template<class T>
class BST
{
public:
typedef Node<T> Node;
BST()//构造
:_root(nullptr)
{
}
BST(const BST<T>& val)//拷贝构造---深拷贝
{
//结构也要拷过来,走到什么位置,就把对应的节点创建出来
_root = copy(bst._root);
}
//递归拷贝节点
Node* copy(Node* root)
{
if (root == nullptr)
return nullptr;
Node* cur = new(root->_val);
cur->_left = copy(root->_left);
cur->_right = copy(root->_right);
return cur;
}
~BST()
{
if (_root)
destroy(_root);
}
//销毁
void destroy(Node* root)
{
if (root)
{
destroy(root->_left);
destroy(root->_right);
delete root;
root = nullptr;
}
}
//查找
Node* find(const T& val)
{
//从根节点开始查找
Node* cur = _root;
while (cur)
{
if (cur->_val == val)
return cur;
else if (cur->_val < val)
cur = cur->_right;
else
cur = cur->_left;
}
//不存在返回空
return nullptr;
}
//插入:1.空树(直接插入) 2.非空树(搜索+插入)还要判断数据是否存在
bool insert(const T& val)
{
//判断是否为空树
if (_root == nullptr)
{
_root = new Node(val);
return true;
}
//搜索插入的位置
Node* cur = _root;
Node* parent = nullptr;
while (cur)
{
parent = cur;
if (cur->_val == val)
return false;
else if (cur->_val < val)
cur = cur->_left;
else
cur = cur->_right;
}
//确定新插入数据的左右位置
cur = new Node(val);
if (parent->_val < val)
parent->_right = cur;
else
parent->_left = cur;
return true;
}
//删除
bool erase(const T& val)
{
//1.判断根节点
if (_root == nullptr)
return false;
Node* cur = _root;
Node* parent = nullptr;
//查找
while (cur)
{
if (cur->_val == val)
break;
else if (cur->_val < val)
{
parent = cur;//更新节点
cur = cur->_right;
}
else
{
parent = cur;
cur = cur->_left;
}
}
//判断cur是否为空
if (cur == nullptr)
return false;
//删除:叶子or非叶子?
//1.叶子节点
if (cur->_left == nullptr && cur->_right == nullptr)
{
//判断删除的是否为根节点
if (cur == _root)
{
_root = nullptr;
}
else
{
if (parent->_left == cur)
parent->_left == nullptr;
else
parent->_right == nullptr;
}
delete cur;
}
//2.非叶子节点
//左边为空,右边不为空
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
{
//左右孩子都存在
//1.找左子树最右节点
Node* child = cur->_left;
parent = cur;
while (child->_right)
{
parent = child;
child = child->_right;
}
//2.最右节点的值覆盖cur位置的值
cur->_val = child->_val;
//3.重新链接
if (parent->_left == child)
parent->_left = child->_left;
else
parent->_right = child->_left;
//4.删除最右节点
delete child;
}
return true;
}
//中序遍历:是有序的
void inorder()
{
_inorder(_root);
cout << endl;
}
void _inorder(Node* root)
{
if (root)
{
_inorder(root->_left);
cout << root->_val << " ";
_inorder(root->_right);
}
}
private:
Node* _root;
};
word
,判断该单词是否正确template <class K>
struct Node
{
K _key;
Node* _left;
Node* _right;
Node(const K& key = K())
:_key(key)
, _left(nullptr)
, _right(nullptr)
{
}
};
template <class K>
class BST
{
public:
typedef Node<K> Node;
//构造函数
BST()
:_root(nullptr)
{
}
//拷贝构造
BST(const BST<K>& key)//拷贝构造---深拷贝
{
//结构也要拷过来,走到什么位置,就把对应的节点创建出来
_root = copy(bst._root);
}
//递归拷贝
Node* copy(Node* root)
{
if (root == nullptr)
return nullptr;
Node* cur = new(root->_key);
cur->_left = copy(root->_left);
cur->_right = copy(root->_right);
return cur;
}
//析构函数
~BST()
{
if (_root)
destory(_root);
}
//销毁
void destory(Node* root)
{
if (root)
{
destory(root->_left);
destory(root->_right);
delete root;
root = nullptr;
}
}
//查找
Node* find(const K& key)
{
//从根节点开始查找
Node* cur = _root;
while (cur)
{
if (cur->_key == key)
return cur;
else if (cur->_key < key)
cur = cur->_right;
else
cur = cur->_left;
}
return nullptr;
}
//插入
bool insert(const K& key)
{
//判断是否为空树
if (_root == nullptr)
{
_root = new Node(key);
return true;
}
//搜索插入的位置
Node* cur = _root;
Node* parent = nullptr;
while (cur)
{
parent = cur;
if (cur->_key == key)
return false;
else if (cur->_key < key)
cur = cur->_right;
else
cur = cur->_left;
}
cur = new Node(key);
//确定新插入数据的左右位置
if (parent->_key < key)
parent->_right = cur;
else
parent->_left = cur;
return true;
}
//删除
bool erase(const K& key)
{
if (_root == nullptr)
return false;
Node* cur = _root;
Node* parent = nullptr;
while (cur)
{
if (cur->_key == key)
break;
else if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else
{
parent = cur;
cur = cur->_left;
}
}
if (cur == nullptr)
return false;
//删除操作
// 1. 叶子节点
if (cur->_left == nullptr && cur->_right == nullptr)
{
//判断删除的是否为根节点
if (cur == _root)
{
_root = nullptr;
}
else
{
if (parent->_left == cur)
parent->_left = nullptr;
else
parent->_right = nullptr;
}
delete cur;
}
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
{
//左右孩子都存在
//1. 找左子树的最右节点
Node* child = cur->_left;
parent = cur;
while (child->_right)
{
parent = child;
child = child->_right;
}
//2. 用最右节点的值覆盖当前cur位置的值
cur->_key = child->_key;
//3. 重新链接
if (parent->_left == child)
parent->_left = child->_left;
else
parent->_right = child->_left;
//4. 删除最右节点
delete child;
}
return true;
}
//中序遍历:是有序的
void inorder()
{
_inorder(_root);
cout << endl;
}
void _inorder(Node* root)
{
if (root)
{
_inorder(root->_left);
cout << root->_key << " ";
_inorder(root->_right);
}
}
private:
Node* _root;
};
key
,都有与之对应的值value
,即
的键值对
就构成一种键值对template <class K, class V>
struct Node
{
K _key;
V _val;
Node* _left;
Node* _right;
Node(const K& key = K(), const V& val = V())
: _key(key)
,_val(val)
, _left(nullptr)
, _right(nullptr)
{
}
};
template <class K, class V>
class BST
{
public:
typedef Node<K, V> Node;
Node* find(const K& key)
{
//从根节点开始查找
Node* cur = _root;
while (cur)
{
if (cur->_key == key)
return cur;
else if (cur->_key < key)
cur = cur->_right;
else
cur = cur->_left;
}
return nullptr;
}
BST()
:_root(nullptr)
{
}
Node* copy(Node* root)
{
if (root == nullptr)
return nullptr;
Node* cur = new Node(root->_key, root->_val);
cur->_left = copy(root->_left);
cur->_right = copy(root->_right);
return cur;
}
BST(const BST<K, V>& bst)
{
_root = copy(bst._root);
}
void destory(Node* root)
{
if (root)
{
destory(root->_left);
destory(root->_right);
delete root;
root = nullptr;
}
}
~BST()
{
if (_root)
destory(_root);
}
bool insert(const K& key, const V& val)
{
//判断是否为空树
if (_root == nullptr)
{
_root = new Node(key, val);
return true;
}
//搜索插入的位置
Node* cur = _root;
Node* parent = nullptr;
while (cur)
{
parent = cur;
if (cur->_key == key)
return false;
else if (cur->_key < key)
cur = cur->_right;
else
cur = cur->_left;
}
cur = new Node(key, val);
//确定新插入数据的左右位置
if (parent->_key < key)
parent->_right = cur;
else
parent->_left = cur;
return true;
}
bool erase(const K& key)
{
if (_root == nullptr)
return false;
Node* cur = _root;
Node* parent = nullptr;
while (cur)
{
if (cur->_key == key)
break;
else if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else
{
parent = cur;
cur = cur->_left;
}
}
if (cur == nullptr)
return false;
//删除操作
// 1. 叶子节点
if (cur->_left == nullptr && cur->_right == nullptr)
{
//判断删除的是否为根节点
if (cur == _root)
{
_root = nullptr;
}
else
{
if (parent->_left == cur)
parent->_left = nullptr;
else
parent->_right = nullptr;
}
delete cur;
}
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
{
//左右孩子都存在
//1. 找左子树的最右节点
Node* child = cur->_left;
parent = cur;
while (child->_right)
{
parent = child;
child = child->_right;
}
//2. 用最右节点的值覆盖当前cur位置的值
cur->_key = child->_key;
cur->_val = child->_val;
//3. 重新链接
if (parent->_left == child)
parent->_left = child->_left;
else
parent->_right = child->_left;
//4. 删除最右节点
delete child;
}
return true;
}
private:
Node* _root;
};