直接上代码,很多解释我都再代码里面有说明,如果有什么问题欢迎交流
#include <iostream>
#include <string>
#include <utility>
#include <algorithm>
using namespace std;
struct Node
{
int key;
Node * left;
Node * right;
Node(int key)//结构体的构造函数,结构体默认都是public,而class属性默认private
{
this->key = key;
this->left = this->right = nullptr;
}
};
class BST_HWQ
{
private:
Node * header;
private:
void destroy(Node * node);
Node * insert_real(int key, Node *& node);
Node *& find_real(int key, Node *& node);
void in_order(Node * node);
public:
BST_HWQ();
~BST_HWQ();
Node * insert(int key);
Node * find(int key);
void erase(int key);
void print();
};
BST_HWQ::BST_HWQ() //构造函数
{
header = new Node(0);
}
BST_HWQ::~BST_HWQ() //析构函数
{
destroy(header->left);
delete header;
header = nullptr;
}
void BST_HWQ::destroy(Node * node)
{
if (node == nullptr)
return;
destroy(node->left);//递归删除节点
destroy(node->right);
delete node; //释放指针指向的内存,指针本身变成野指针,要赋值nullptr
}
Node * BST_HWQ::insert_real(int key, Node *& node)//返回Node型指针,参数为插入数值和Node*类型的引用变量
{
if (node == nullptr)
return node = new Node(key);
if (key < node->key) //递归的找位置然后插入
return insert_real(key, node->left);
else if (key > node->key)
return insert_real(key, node->right);
else
return nullptr; //相等不插入
}
Node *& BST_HWQ::find_real(int key, Node *& node)//递归查找元素
{
if (node == nullptr)
return node;
if (key < node->key)
return find_real(key, node->left);
else if (key > node->key)
return find_real(key, node->right);
else
return node;
}
void BST_HWQ::in_order(Node * node) //中序遍历二叉树
{
if (node == nullptr)
return;
in_order(node->left);
cout << node->key << " ";
in_order(node->right);
}
Node * BST_HWQ::insert(int key)//对外调用接口,在内部调用insert_real
{
return insert_real(key, header->left);
}
Node * BST_HWQ::find(int key)
{
return find_real(key, header->left);
}
void BST_HWQ::erase(int key) //要先找到值所在的节点,然后删除之后要对其子节点进行调整
{
Node *& p = find_real(key, header->left);//Node*类型的引用,操作引用变量相当于操作"实际"变量
if (p)
{
Node * t = p; //创建一个临时指针指向要删除的节点
if (t->left && t->right)
{
// 找到 t 的后继结点
Node * y = t; //y用于保存当前节点的父亲节点
Node * x = t->right;
while (x->left)
{
y = x;
x = x->left;
}
// 将后继结点的右子树接上它的父亲
if (y == t)
y->right = x->right;//大家如果清楚.和->的含义的话,下面的代码就不会觉得矛盾了
else //->得到的是那个东西的地址,.得到的是那个东西的值
y->left = x->right;
// 用后继结点替换要删除的结点 t
p = x;
x->left = t->left;
x->right = t->right;
}
else
p = t->left ? t->left : t->right; //判断左孩子是否为真
delete t;
}
}
void BST_HWQ::print()
{
in_order(header->left);
cout << endl;
}
int main()
{
BST_HWQ bst_hwq;
// test "insert"
bst_hwq.insert(7);//第一个插入了什么根就决定了
bst_hwq.insert(2);
bst_hwq.insert(1); bst_hwq.insert(1);//不会插入相同的
bst_hwq.insert(5);
bst_hwq.insert(3);
bst_hwq.insert(6);
bst_hwq.insert(4);
bst_hwq.insert(9);
bst_hwq.insert(8);
bst_hwq.insert(11); bst_hwq.insert(11);
bst_hwq.insert(10);
bst_hwq.insert(12);
bst_hwq.print(); // 1 2 3 4 5 6 7 8 9 10 11 12//二叉查找的中序遍历结果就是排序结果
// test "find"
Node * p = nullptr;
cout << ((p = bst_hwq.find(2)) ? p->key : -1) << endl; // 2 判断p是否为真
cout << ((p = bst_hwq.find(100)) ? p->key : -1) << endl; // -1
// test "erase"
bst_hwq.erase(2);
bst_hwq.print(); // 1 3 4 5 6 7 8 9 10 11 12
bst_hwq.erase(10);
bst_hwq.erase(9);
bst_hwq.print(); // 1 3 4 5 6 7 8 11 12
return 0;
}