#include <iostream>
using namespace std;
typedef struct TreeNode {
int data;
struct TreeNode *lchild;
struct TreeNode *rchild;
} TreeNode;
//查找
TreeNode *bstSearch(TreeNode *T, int key) {
if (T) {
if (T->data == key) {
return T;
} else if (key < T->data) {
return bstSearch(T->lchild, key);
} else {
return bstSearch(T->rchild, key);
}
} else {
return nullptr;
}
}
void preOrder(TreeNode *T) {
if (T == nullptr) {
return;
}
preOrder(T->lchild);
cout << T->data << " ";
preOrder(T->rchild);
}
void bstInsert(TreeNode **T, int key) {
if (*T == nullptr) {
*T = (TreeNode *) malloc(sizeof(TreeNode));
(*T)->data = key;
(*T)->rchild = nullptr;
(*T)->lchild = nullptr;
} else if (key < (*T)->data) {
bstInsert(&(*T)->lchild, key);
} else if (key > (*T)->data) {
bstInsert(&(*T)->rchild, key);
} else {
return;
}
}
//查找父结点
TreeNode *searchFather(TreeNode *T, int key) {
TreeNode *t = T;
if (T == nullptr || T->data == key) { //空树或者key为根节点的关键字
return nullptr;
}
while (t->rchild || t->lchild) { //有孩子
if (key < t->data && t->lchild->data != key) { //key值<该节点关键字 并且 key不是该节点的左孩子
t = t->lchild;
} else if (key > t->data && t->rchild->data != key) { //key值>该节点关键字 并且 key不是该节点的右孩子
t = t->rchild;
} else if (key < t->data && t->lchild->data == key) {
return t;
} else if (key > t->data && t->rchild->data == key) {
return t;
}
}
return nullptr;
}
//删除操作中查找删除节点左子树的最大值,用来代替删除节点
TreeNode *del_find_lchild(TreeNode *T) {
TreeNode *t = T;
while (t->rchild) {
t = t->rchild;
}
return t;
}
//删除操作中查找删除节点右子树的最小值,用来代替删除节点
TreeNode *del_find_rchild(TreeNode *T) {
TreeNode *t = T;
while (t->lchild) {
t = t->lchild;
}
return t;
}
void bstDel(TreeNode **T, int key) {
TreeNode *dt = bstSearch(*T, key); //找到要删除的节点
if (dt) { //存在该节点
// TreeNode *df = del_find_lchild(dt); //要删除节点的父节点。
TreeNode *df = searchFather(*T, key); //找到父亲节点
if(df){ //如果有父节点
if (dt->rchild == nullptr && dt->lchild == nullptr) { //该节点如果是叶子节点,直接删除
//删除节点
if (key < df->data) {
free(df->lchild);
df->lchild = nullptr;
} else {
free(df->rchild);
df->rchild = nullptr;
}
} else { //非叶子节点
if (dt->lchild) {//左子树不为空
TreeNode *l_maxChild = del_find_lchild(dt->lchild); //要删除节点的左子树中最大的节点
TreeNode *l_maxChild_f = searchFather(*T,l_maxChild->data);//要删除节点的左子树中最大节点的父节点
if(l_maxChild->data < l_maxChild_f->data){
l_maxChild_f->lchild = nullptr;
}else{
l_maxChild_f->rchild = nullptr;
}
l_maxChild->lchild = dt->lchild;
l_maxChild->rchild = dt->rchild;
if (key < df->data) { //如果要删除的节点是其父节点的左孩子
df->lchild = l_maxChild; //用要删除节点的左子树中最大的节点代替要删除的节点
} else {
df->rchild = l_maxChild;
}
free(dt); //释放掉要删除节点的内存
} else { //右子树不为空
TreeNode *r_minChild = del_find_rchild(dt->rchild); //要删除节点的右子树中最小的节点
TreeNode *r_minChild_f = searchFather(*T,r_minChild->data);//要删除节点的右子树中最小节点的父节点
if (r_minChild->data < r_minChild_f->data){
r_minChild_f->lchild = nullptr;
}else{
r_minChild_f->rchild = nullptr;
}
r_minChild->lchild = dt->lchild;
r_minChild->rchild = dt->rchild;
if (key < df->data) { //如果要删除的节点是其父节点的左孩子
df->lchild = r_minChild; //用要删除节点的左子树中最大的节点代替要删除的节点
} else {
df->rchild = r_minChild;
}
free(dt); //释放掉要删除节点的内存
}
}
}
else{ //要删除的是根节点
if(dt->lchild){ //左子树不为空
TreeNode *l_maxChild = del_find_lchild(dt->lchild);
TreeNode *l_maxChild_f = searchFather(*T, l_maxChild->data);
if (l_maxChild->data < l_maxChild_f->data){ //把左子树最大的值删除
l_maxChild_f->lchild = nullptr;
}else{
l_maxChild_f->rchild = nullptr;
}
l_maxChild->lchild = dt->lchild; //把要删除节点的左右孩子复制到左子树最大的孩子上
l_maxChild->rchild = dt->rchild;
*T = l_maxChild;
free(dt);
}else{ //左子树为空
*T = dt->rchild;
free(dt);
}
}
}
}
int main() {
TreeNode *T = nullptr;
int nums[9] = {7,5,15,4,6,12,18,9,13};
for (int i = 0; i < 9; i++) {
bstInsert(&T, nums[i]);
}
preOrder(T); //中序遍历 4 5 6 7 9 12 13 15 18
bstDel(&T,9);
cout << endl;
preOrder(T); //4 5 6 7 12 13 15 18
}
二叉排序树的增删查(C++)
最新推荐文章于 2023-01-19 20:37:21 发布