视频教程推荐:懒猫老师-数据结构-(58)二叉排序树的删除(二叉查找树)_哔哩哔哩_bilibili
直接上代码,有简单注释。
#include<iostream>
#include<array>
#define DataType int
using namespace std;
struct BST_node
{
DataType data;
BST_node *left;
BST_node *right;
};
class BST
{
private:
BST_node* root;
public:
BST(DataType arr[], size_t arr_size);
~BST() { release(root); }; //可以琢磨一下为何要把release放入析构,而不直接用析构来释放内存。
void in_traverse() { traverse(root); }//中序遍历(即按从小到大遍历),同上,思考一下(提示:递归与root)
void insert(DataType key) { bi_insert(root, key); }//插入
void del(DataType key) { root = bi_delete(root, key); }//删除
BST_node* search(DataType key) { return bi_search(root, key); }//寻找某个指定节点,并返回其地址
private:
void traverse(BST_node*);//中序遍历
void release(BST_node* node);//用于析构
void bi_insert(BST_node*& nood, DataType key);//注意引用
BST_node* bi_delete(BST_node* node, DataType key);
BST_node* bi_search(BST_node* node, DataType key);
};
void BST::bi_insert(BST_node* &Root, DataType data)
{
if (Root == NULL)
{
BST_node* new_node = new BST_node;
new_node->data = data;
new_node->left = NULL;
new_node->right = NULL;
Root = new_node;
}
else
{
if (Root->data > data)
bi_insert(Root->left, data);
if(Root->data<data)
bi_insert(Root->right, data);
}
}
void BST::release(BST_node* node)
{
if (node == NULL)
return;
release(node->left);
release(node->right);
delete node; //注意!后序遍历删除!!
return;
}
BST::BST(DataType arr[], size_t arr_size)
{
root = NULL;
for (int i = 0; i < arr_size; i++)
{
bi_insert(root, arr[i]);
}
}
void BST::traverse(BST_node* node)
{
if (node == NULL)
return;
traverse(node->left);
cout << node->data << " ";//只有中序遍历,才能从小到大打印
traverse(node->right);
}
BST_node* BST::bi_search(BST_node* node, DataType key)
{
if (node == NULL)
return NULL;
if (node->data > key)
return bi_search(node->left, key);//return函数返回值
else if (node->data < key)
return bi_search(node->right, key);
else
return node;
}
BST_node* BST::bi_delete(BST_node* root, DataType key)
{
BST_node* target = bi_search(root, key);
BST_node* copy_root = root;
BST_node* temp = NULL;
if (root->data == key)//情况一:根节点即为被删除的节点
{
temp = root->left;
root = root->right;
while (root->left != NULL)
root = root->left;
root->left = temp;
return copy_root->right;
}
else
{
BST_node* temp1 = NULL;
while ((root->left==NULL || root->left->data != key) &&(root->right==NULL || root->right->data != key)) //4种可能的情况,最里面的括号中的顺序不可反!!!
key < root->data ? root = root->left : root = root->right;
key < root->data ? temp = root->left : temp = root->right;
temp1 = temp->right;
if (temp1 == NULL) //情况二:被删节点没有右子树,则直接将被删节点的左子树连到被删节点的父节点(作为父节点的右子树还是左子树需要判断,见下if-else)
{
if (temp->data > root->data)
root->right = temp->left;
else
root->left = temp->left;
return copy_root;
}
else //被删节点有右子树,则将被删节点的左子树连到右子树的最左叶子节点
{
while (temp1->left != NULL)
temp1 = temp1->left;
temp1->left = temp->left;
if (temp->data < root->data)
{
root->left = temp->right;
delete temp;
return copy_root;
}
else
{
root->right = temp->right;
delete temp;
return copy_root;
}
}
}
}
int main()
{
array<int, 10>arr{ 12,32,43,23,45,15,76,48,98,56 };//刚学习STL,所以采用STL的数组,也可用普通数组
BST bi_ser_tre(arr.data(), arr.size());
bi_ser_tre.in_traverse();
cout << endl;
cout << "插入9:" << endl;
bi_ser_tre.insert(9);
bi_ser_tre.in_traverse();
cout << endl;
cout << "删除76:" << endl;
bi_ser_tre.del(76);
bi_ser_tre.in_traverse();
return 0;
}