二叉搜索树
二叉搜索树
- 二叉搜索树结构
- 二叉搜索树插入
- 二叉搜索树的查找
- 二叉搜索树的删除
- 二叉搜索树中序便利
- 二叉搜索树默认成员函数实现
二叉搜索树结构
template<class K, class V>
class BinarySeacherTreeNode
{
public:
BinarySeacherTreeNode(K Key = new K, V Val = new V) :left(NULL), right(NULL), key(Key), val(Val) {}
BinarySeacherTreeNode* left;
BinarySeacherTreeNode* right;
K key;
V val;
};
template<class K, class V>
class BinarySeacherTree
{
public:
using Node = BinarySeacherTreeNode<K, V>;
private:
Node* head = NULL;
二叉搜索树插入
插入思路:
定义一个cur指针和一个parent指针;插入的key比cur指向的key大就往右边走cur走一次parent跟新知道cur为空此时判断parent的key和要插入的key的大小来决定插入左边还是右边
bool Insert(const K& key, const V& val)
{
if (head == NULL)
{
head = new Node(key, val);
return true;
}
Node* parent = head;
Node* cur = head;
while (cur)
{
if (key > cur->key)
{
parent = cur;
cur = cur->right;
}
else if (key < cur->key)
{
parent = cur;
cur = cur->left;
}
else
{
return false;
}
}
//上面循环就是找到插入的父节点
//下面还要判断插入父节点的左右孩子
cur = new Node(key, val);
if (parent->key < key)
{
parent->right = cur;
}
else
{
parent->left = cur;
}
return true;
}
二叉搜索树的查找
查找思路:
如果查找的key大于当前节点的key就去右边反之左边,相等返回该节点
直到cur为空还没找到就返回空指针
Node* Find(const K& key)
{
Node* cur = head;
while (cur)
{
if (cur->key < key)
{
cur = cur->right;
}
else if (cur->key > key)
{
cur = cur->left;
}
else
{
return cur;
}
}
//cout << "找不到" << endl;
return NULL;
}
二叉搜索树的删除
删除思路:
- 先找到要删除的节点
- 判断要删除的节点有结构孩子
- 删除的节点有一个或一个孩子
该情况如下:
至于0个孩子节点可以看做有一个空节点进行处理
我们找到只需要把parent指向cur的孩子这里还要进行判断首先就是看cur是parent的左孩子还是右孩子,之后在判断cur的那一个孩子是哪一个最后进行连接即可
注意:
这时候我们要考虑删除的是根节点的话我们直接改变根节点的指向就可以了- 删除的节点有两个节点
该情况如下:
此时我们要进行代替法就是找cur的右树中最左端的节点或者左子树最右端的节点交换里面的值然后删除代替的那个节点即可
bool Erase(const K& key)
{
Node* cur = head;
Node* parent = head;
while (cur)
{
if (key > cur->key)
{
parent = cur;
cur = cur->right;
}
else if (key < cur->key)
{
parent = cur;
cur = cur->left;
}
else
{
//1.删除的节点有2个孩子
if (cur->left && cur->right)
{
//去右树找找左的节点来代替然后析构该节点
Node* replaceparent = cur;
Node* replace = cur->right;
while (replace->left)
{
replaceparent = replace;
replace = replace->left;
}
cur->val = replace->val;
if (replaceparent->right == replace)
{
replaceparent->right = replace->right;
delete replace;
replace = NULL;
}
else
{
replaceparent->left = replace->right;
delete replace;
replace = NULL;
}
}
//2.删除的节点有0或1个孩子
else
{
//如果删除的是根节点直接跟新我们的根节点
if (cur == head)
{
if (cur->left) head = cur->left;
else head = cur->right;
}
else
{
if (parent->left == cur)
{
if (cur->left) parent->left = cur->left;
else parent->left = cur->right;
}
else
{
if (cur->left) parent->right = cur->left;
else parent->right = cur->right;
}
}
}
return true;
}
}
return false;
}
二叉搜索树中序便利
void InOrder()
{
_inorder(head);
}
void _inorder(Node* head)
{
if (head == NULL)return;
_inorder(head->left);
cout << "key:" << head->key << " val:" << head->val << " ";
_inorder(head->right);
}
二叉搜索树默认成员函数实现
拷贝构造函数:
BinarySeacherTree(const BinarySeacherTree& b) { this->head = createtree(b.head); } Node* createtree(Node* hea) { if (hea == NULL) return nullptr; Node* root = new Node(hea->key, hea->val); root->left = createtree(hea->left); root->right = createtree(hea->right); return root; }
赋值重载:
BinarySeacherTree<K, V> operator=( BinarySeacherTree<K, V> tem) { //这里参数不要传入引用 std::swap(head, tem.head); return *this; }
析构函数:
~BinarySeacherTree() { destory(head); head = NULL; } void destory(Node* hea) { if (hea == NULL)return; destory(hea->left); destory(hea->right); delete hea; hea = NULL; }