模拟实现
#pragma once
template<class T>
struct Tree
{
T _node;
Tree* _lift = nullptr;
Tree* _right = nullptr;
Tree(const T&k)
:_node(k)
{}
};
template<class T>
class BSTree
{
public://遍历,插入,删除,查找
typedef Tree<T> Tree;
BSTree()
:_root(nullptr)
{}
BSTree(const T& key)
:_root(key)
{}
void Traverse()//中序遍历
{
_Traverse(_root);
}
bool Insert(T key)//插入形参搜索树
{
if (_root == nullptr)
_root = new Tree(key);//空树直接作为头
Tree* parent = nullptr;
Tree* cur = _root;
while (cur)
{
if (key < cur->_node)//如果key小于node 则在左子树
{
parent = cur;
cur = cur->_lift;
}
else if (key > cur->_node)
{
parent = cur;
cur = cur->_right;
}
else
return false;//不应该插入相同值
}//现在找到了空子叶
if (parent->_node > key)//如果小则应该插入到左边
{
parent->_lift = new Tree(key);
}
else//否则右边
{
parent->_right = new Tree(key);
}
return true;
}
bool Earse(const T&key)//删除某一节点
{
if (_root == nullptr)
return false;//空树
Tree* parent = _root;
Tree* cur = _root;
while (cur)
{
if (key < cur->_node)//如果key小于node 则在左子树
{
parent = cur;
cur = cur->_lift;
}
else if (key > cur->_node)
{
parent = cur;
cur = cur->_right;
}
else//找到key了
{
//三种情况,key左子树为空(parent直接连),key右子树为空(parent直接连),key左右都不为空(找右子树最小的替换,然后删)
if (cur->_lift == nullptr)
{
if (parent != cur)
{
if (key < parent->_node)
{
parent->_lift = cur->_right;
}
else
{
parent->_right = cur->_right;
}
delete cur;
}
else
{
//要删除父节点,且左子树为空
_root = cur->_right;
delete cur;
}
}
else if (cur->_right == nullptr)//右子树为空
{
if (parent != cur)
{
if (key < parent->_node)
{
parent->_lift = cur->_lift;
}
else
{
parent->_right = cur->_lift;
}
delete cur;
}
else
{
//要删除父节点,且左子树为空
_root = cur->_right;
delete cur;
}
}
else//左右子树都不为空
{
//找右子树里最小的,与cur交换,然后delete叶子
parent = cur;
Tree*tmp = cur->_right;
while (tmp->_lift)
{
parent = tmp;
tmp = tmp->_lift;//一直找最小
}
if (tmp->_right == nullptr)//叶子没右子树
{
swap(tmp->_node, cur->_node);
if (parent->_right != tmp)
parent->_lift = nullptr;
else
parent->_right = nullptr;
delete tmp;
}
else
{
swap(tmp->_node, cur->_node);
if (parent == cur)
{
parent->_right= tmp->_right;
}
else
{
parent->_lift = tmp->_right;
}
delete tmp;
}
}
return true;
}
}
return false;//没找到false
}
bool InsertRet(T key)//递归插入节点
{
return InsertR(_root, key);
}
bool EarseRrt(T key)//递归删除
{
return EarseR(_root, key);
}
private:
void _Traverse(Tree* root)//中序遍历
{
if (root == nullptr)
return;
_Traverse(root->_lift);
cout << root->_node << " ";
_Traverse(root->_right);
}
bool InsertR(Tree*& root, T key)//递归插入节点
{
if (root == nullptr)//找到了,就是要空节点
{
root = new Tree(key);
return true;
}
if (key < root->_node)
{
return InsertR(root->_lift, key);//在左子树里面找
}
else if (key > root->_node)
{
return InsertR(root->_right, key);//在右子树里面找
}
else//找到一样的了
{
return false;
}
}
bool EarseR(Tree*& root, T key)//递归删除
{
if (root == nullptr)
{
return false;//没找到
}
if (key < root->_node)
{
return EarseR(root->_lift, key);//在左子树里面找
}
else if (key > root->_node)
{
return EarseR(root->_right, key);//在右子树里面找
}
else//找到一样的了
{
if (root->_lift == nullptr)//左子树为空
{
Tree* tmp = root;
root = root->_right;
delete tmp;
}
else if (root->_right == nullptr)//右子树
{
Tree* tmp = root;
root = root->_lift;
delete tmp;
}
else//左右子树都不为空
{
//找右子树里最小的
Tree* parent = root;//最小节点的父亲
Tree* tmp = root->_right;
while (tmp->_lift)
{
parent = tmp;
tmp = tmp->_lift;//在右子树中,一直左走
}
swap(root->_node, tmp->_node);
if (parent != root)
parent->_lift = tmp->_right;
else
parent->_right = tmp->_right;
delete tmp;
}
return true;
}
}
Tree* _root;
};
测试代码
#include<iostream>
using namespace std;
#include"BSTree.hpp"
int main()
{
int arr[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13,0,2,5,11};
BSTree<int> tree;
for (auto e : arr)
{
tree.InsertRet(e);
}
tree.Traverse();
cout << endl;
for (auto e : arr)
{
cout << "Ҫɾǣ" << e << endl;
tree.EarseRrt(e);
tree.Traverse();
cout << endl;
}
return 0;
}