写在前面:
1,*&一起用的参数:即指针的别名。通常用于在某一个函数修改指针变量的copy时,同步修改真正的指针变量
2,关于delete:很基本的一点是,new完内存以后才能对其使用delete,对象手动调用delete后,会调用析构函数
3,const是个指针常量!只能修改其内容,不要想着改方向
二叉树的删除
|| 二叉树的删除需要分三种情况考虑:删除树叶节点,删除带有一个树叶的子节点,删除带有两个树叶的子节点,
-
删除树叶节点:如果是树叶,直接删除
-
删除带有一个树叶的子节点:将待删除节点的上一个节点指向其子节点
-
删除带有两个树叶的子节点:删除该节点就转换为,用其右子树中最小的一个节点的值覆盖该节点中的值,然后再删除该子节点
//针对第三种情况的详细思路
- 因为要将删除节点转换后所形成的新树依然满足二叉搜索树的形式,所以我们需要在它的两个子树找到这样的节点,来进行替换
- 有两种方式找到这种节点。在其右子树的左子树中找到最小值,或者在其左子树的右子树中找到最大值。
- 满足以上条件的节点有这些特征:左子树的左子树为空(即在要删除节点的右子树中没有比它还小的节点了)或者右子树的右子树为空(即在要删除节点的左子树中没有比它还大的节点了)
- 找到这样的节点后,再完成替换与删除操作(第二种类型)就好了
/*
* File: BTree_support delete.cpp
* Author: fang lingjun
* Date: 20200410
*
* Email: fanglj@smbu.edu.cn
*/
//
class BTree {
friend void Delete(BTree*& BT, int val_delete);
friend void hightLitter(BTree*& BT);
private:
bool Empty;
int val;
int deep;
BTree* Right;
BTree* Left;
public:
BTree();
BTree(BTree& t);
~BTree();
void Print();
bool Add(int val_new);
BTree* ProtoMin();
};
void hightLitter(BTree*& BT);
void Delete(BTree*& BT, int val_delete);
//
BTree::BTree() {
Empty = true;
}
BTree::BTree(BTree& BT) {
Empty = true;
if (BT.Empty) return;
Empty = false;
val = BT.val;
Left = new BTree(*BT.Left);
Right = new BTree(*BT.Right);
}
BTree::~BTree() {
if(Empty) return;
delete Left;
delete Right;
}
int a = -1;
bool BTree::Add(int val_new) { // 增添操作(把深度放进数据结构,作为一个顺便获得的属性)
int& A = a;
A++;
if (Empty == true) {
Empty = false;
deep = A;
val = val_new;
Left = new BTree();
Right = new BTree();
A = -1;
return true;
}
// 多个if一般都可以简化为三目操作符
return (val_new == val) ? false : (val_new < val) ? Left->Add(val_new) : Right->Add(val_new);
}
BTree* BTree::ProtoMin() { // 找到该二叉搜索树中的最小值
return (Left->Left->Empty) ? this : Left->ProtoMin();
}
void hightLitter(BTree*& BT){ // 高度减一
if (BT->Empty == true) return ;
BT->deep--;
hightLitter(BT->Left);
hightLitter(BT->Right);
}
void Delete(BTree*& BT,int val_delete) { // 删除操作
if (BT->Empty == true) return;
if (val_delete < BT->val) Delete(BT->Left,val_delete);
else if (val_delete > BT->val) Delete(BT->Right, val_delete);
else if (BT->Left->Empty == false && BT->Right->Empty == false) {
BT->val = (BT->Right->ProtoMin())->val;
Delete(BT->Right, BT->val);
}
else {
if (BT->Left->Empty == false) {
BT = BT->Left;
hightLitter(BT);
}
if (BT->Right->Empty == false) {
BT = BT->Right;
hightLitter(BT);
}
}
}