二叉搜索树BST的插入、删除和搜索(C语言实现)
// 定义二叉树结构
typedef struct TreeNode{
float val; struct TreeNode *left, *right;}TreeNode;
void insertBST(TreeNode **root, float x){
TreeNode *cur = *root, *newnode = (TreeNode *)malloc(sizeof(TreeNode)); newnode->val = x; newnode->left = NULL; newnode->right = NULL;
if (!cur) {
*root = newnode; return; }
while (cur){
if (x < cur->val){
if (cur->left) cur = cur->left; else {
cur->left = newnode; return; }
} else {
if (cur->right) cur = cur->right; else {
cur->right = newnode; return; } }
}
}
void searchBST(TreeNode *root, float x, TreeNode **xnode) {
TreeNode *cur = root;
*xnode = NULL;
while (cur) {
if (fabs(x - cur->val) < 1e-5) {
*xnode = cur; return; }
else if (x < cur->val) cur = cur->left;
else cur = cur->right;
}
}
void removeFromBST(TreeNode **root, float x){
// 使用**root是因为可能会改变根节点
TreeNode *cur = *root, *pre = NULL;
while (cur){
// 查找节点x
if (fabs(x - cur->val) < 1e-5) {
break;} pre = cur;
if (x < cur->val) cur = cur->left; else cur = cur->right;
}
if (!cur) return; // 没有找到节点x,直接返回
if ( !(cur->left) && !(cur->right)){
// 情况1:删除叶子节点
if (pre){
// 如果不是根节点
if (pre->left == cur) pre->left = NULL; else pre->right = NULL; // 删除的方法是将父节点的指针指向NULL
} else{
*root = NULL; }
free(cur);
}else if (!(cur->left) || !(cur->right)){
// 情况2:删除有一个子节点的节点
TreeNode *tmp = cur->left ? cur->left : cur->right;
if (pre) {
// 如果不是根节点
if (pre->left == cur) pre->left = tmp; else pre->right = tmp; // 删除的方法是将父节点的指针指向子节点
} else {
*root = tmp; }
free(cur);
}else{
// 情况3:删除有两个子节点的节点
TreeNode *tmp = cur->right, *pretmp = cur; while (tmp->left) {
pretmp = tmp; tmp = tmp->left;} cur->val = tmp->val;// 在右子树中找到最小的节点,用最小节点的值替换当前节点的值
// 因为tmp是右子树中的最小节点,所以它不可能有左子节点。它可能有一个右子节点(或者没有任何子节点)。因此,我们可以直接将tmp节点的右子节点连接到tmp的父节点(即pretmp)。
if (pretmp->left == tmp) pretmp->left = tmp->right; else pretmp->right = tmp->right;
free(tmp);
}
}