二叉搜索树BST的插入、删除和搜索(C语言实现)

二叉搜索树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);
    }
}

猜你喜欢

转载自blog.csdn.net/Cony_14/article/details/141829242