接前一篇博文添加二叉查找树的元素删除功能。
#include <stdio.h>
#include <stdlib.h>
//二叉查找树的节点
struct bst_node {
int value;
struct bst_node *left;
struct bst_node *right;
};
typedef struct bst_node Bst_Node;
typedef struct bst_node *P_Bst_Node;
typedef struct bst_node *Bin_Search_Tree;
typedef struct bst_node **P_Bin_Search_Tree;
void clear_bst(P_Bin_Search_Tree);
void insert_bst(P_Bin_Search_Tree, int);
void print_bst(Bin_Search_Tree);
void del_bst(P_Bin_Search_Tree, int, P_Bst_Node);
P_Bst_Node find_min(Bin_Search_Tree);
int main() {
printf("Hello, World!\n");
char a[3][4];
char b = 'a';
int i, j;
for (i = 0; i < 3; ++i) {
for (j = 0; j < 4; ++j) {
a[i][j] = (char) b++;
}
}
for (i = 0; i < 3; ++i) {
for (j = 0; j < 4; ++j) {
printf("%c ", a[i][j]);
}
printf("\n");
}
printf("\n");
char (*pc)[4];
char *pd;
for (i = 0, pc = a; i < 3; ++i) {
for (j = 0, pd = *(pc + i); j < 4; ++j) {
printf("%c ", *(pd + j));
}
printf("\n");
}
printf("\n");
Bin_Search_Tree bst = NULL;
P_Bin_Search_Tree p_bst = &bst;
insert_bst(p_bst, 1);
insert_bst(p_bst, 2);
insert_bst(p_bst, 3);
insert_bst(p_bst, 0);
insert_bst(p_bst, -1);
insert_bst(p_bst, 8);
insert_bst(p_bst, 6);
insert_bst(p_bst, 5);
insert_bst(p_bst, 7);
print_bst(bst);
P_Bst_Node p_min = find_min(bst);
printf("\n%d\n", p_min->value);
del_bst(p_bst, 1, NULL);
printf("\n");
print_bst(bst);
printf("\n");
del_bst(p_bst, 3, NULL);
del_bst(p_bst, 6, NULL);
del_bst(p_bst, -1, NULL);
printf("\n");
print_bst(bst);
#if 1
printf("\n");
clear_bst(p_bst);
bst = NULL;
#endif
return 0;
}
void clear_bst(P_Bin_Search_Tree pt) {
P_Bst_Node pn = *pt;
if (pn != NULL) {
clear_bst(&pn->left);
clear_bst(&pn->right);
free(pn);
pn = NULL;
}
}
void insert_bst(P_Bin_Search_Tree pt, int value) {
if (*pt == NULL) {
P_Bst_Node pn = malloc(sizeof(Bst_Node));
pn->value = value;
pn->left = pn->right = NULL;
*pt = pn;
return;
}
if (value < (*pt)->value) insert_bst(&(*pt)->left, value);
else if (value > (*pt)->value) insert_bst(&(*pt)->right, value);
else;
}
void print_bst(Bin_Search_Tree tree) {
if (tree == NULL) return;
print_bst(tree->left);
printf("%d ", tree->value);
print_bst(tree->right);
}
void del_bst(P_Bin_Search_Tree pt, int x, P_Bst_Node p_parent) {
if (*pt == NULL) return;
P_Bst_Node p_del = *pt;
if (x < p_del->value) del_bst(&p_del->left, x, p_del);
else if (x > p_del->value) del_bst(&p_del->right, x, p_del);
else {
#if 0
printf("\n%d is to be removed!\n", p_del->value);
#endif
if (p_del->left == NULL) {
if (p_del->right == NULL) {//树叶
if (p_parent == NULL) {//p_del是根
*pt = NULL;
} else {
if (p_parent->left == p_del) p_parent->left = NULL;
else if (p_parent->right == p_del) p_parent->right = NULL;
}
} else {//存在右子树
if (p_parent == NULL) {//p_del是根
*pt = p_del->right;
} else {
if (p_parent->left == p_del) p_parent->left = p_del->right;
else if (p_parent->right == p_del) p_parent->right = p_del->right;
}
}
free(p_del);
} else {
if (p_del->right == NULL) {//存在左子树
if (p_parent == NULL) {//p_del是根
*pt = p_del->left;
} else {
if (p_parent->left == p_del) p_parent->left = p_del->left;
else if (p_parent->right == p_del) p_parent->right = p_del->left;
}
free(p_del);
} else {//存在左、右子树
P_Bst_Node p_right_min = find_min(p_del->right);
p_del->value = p_right_min->value;
del_bst(&p_del->right, p_del->value, p_del);
}
}
}
}
P_Bst_Node find_min(Bin_Search_Tree tree) {
return tree == NULL || tree->left == NULL ? tree : find_min(tree->left);
}
运行结果
-1 0 1 2 3 5 6 7 8
-1
-1 0 2 3 5 6 7 8
0 2 5 7 8
Process finished with exit code 0
总结
关键在于:
- 元素的递归删除
- 分析待删除的节点是否有孩子,有几个孩子
- 何时才是对节点进行 free() 的最佳时机