二叉搜索树"remove"函数

binary search tree "remove" function

本文关键字:remove 函数 搜索树      更新时间:2023-10-16

尝试为二进制搜索树编写remove函数。我知道有三种可能的情况需要考虑,但我真的不确定从哪里开始。

我的问题主要源于这样一个事实,即一旦我找到了需要删除的节点,我就需要将它的父节点设置为需要删除节点之后的节点。我应该用光标抓住父节点吗?

我有一个节点的结构:

struct bt_node {
  int data;
  bt_node* left;
  bt_node* right;
};

移除函数的定义如下所示:

void remove(bt_node** top_ref, int data);

谢谢你的帮助!

简单的方法是扩展搜索代码,以便在遍历树时跟踪第二个引用中的"最后一个"父级。这个"扩展"搜索然后返回节点和节点的父节点。

然后通过删除函数使用搜索函数,这样就不必在删除逻辑中做任何花哨的事情。

一种巧妙的方法是使用递归。您要求delete函数将对当前节点的引用返回到调用函数。这样就可以轻松地修改父节点

以下是一些递归代码供您参考:

结构声明:

 typedef struct node {
    int info;
    struct node* lchild;
    struct node* rchild;
}NODE;


删除代码:

NODE* deleteElem(NODE* root, int elem) {
    NODE* save;
    if(root == NULL) {
        printf("Element not in the tree !n");
        return;
    }
    if(root->info == elem) {
        if(root->rchild == NULL && root->lchild == NULL) {                  // no child
            free(root);
            return NULL;
        }
        else if(root->rchild == NULL || root->lchild == NULL) {             // one child
            if(root->rchild == NULL) {
                save = root->lchild;
                free(root);
                return save;
            }
            else {
                save = root->rchild;
                free(root);
                return save;
            }
        }
        else {                                                             // two children
            save = findPred(root->lchild);
            root->info = save->info;
            root->lchild = deleteElem(root->lchild, root->info);
            return root;
        }
    }
    else if(root->info < elem) {
        root->rchild = deleteElem(root->rchild, elem);
    }
    else if(root->info > elem) {
        root->lchild = deleteElem(root->lchild, elem);
    }
    return root;
}
NODE* findPred(NODE* root) {
    static NODE* pred;
    if(root == NULL) {
        return pred;
    }
    else {
        pred = root;
        return findPred(root->rchild);
    }
}

p.S:对不起,我刚刚注意到您函数的原型声明。我希望更改此代码以匹配原型声明应该不会太困难。

你可以试试这个:

void delete_tree(struct tree **ptr,int item) 
{ 
      struct tree *move,*back,*temp; 
      if(*ptr==NULL) 
      { 
               printf("nEmpty tree..............n"); 
               return; 
      } 
      else 
      { 
               move=*ptr; 
               back=move;
               while(move->info!=item) 
               { 
                         back=move;
                         if(item<move->info) 
                         {
                                   move=move->left; 
                         } 
                         else 
                         { 
                                  move=move->right; 
                         } 
               }
               if(move->left!=NULL&&move->right!=NULL) 
               {
                         temp=move->right;
                         while(temp->left!=NULL) 
                         { 
                                  back=temp; 
                                  temp=temp->left; 
                         }
                         move->info=temp->info; 
                         move=temp; 
               }
               if(move->left==NULL&&move->right==NULL) 
               { 
                         if(back->right==move) 
                         { 
                                  back->right=NULL; 
                         } 
                         else 
                         { 
                                  back->left=NULL; 
                         }
                         free(move); 
                         return; 
               }
               if(move->left==NULL && move->right!=NULL) 
               { 
                         if(back->left==move) 
                         { 
                                  back->left=move->right; 
                         } 
                         else 
                         { 
                                  back->right=move->right; 
                         }
                         free(move); 
                         return; 
               }
               if(move->left!=NULL && move->right==NULL) 
               {
                          if(back->left==move) 
                         { 
                                  back->left=move->left; 
                         } 
                         else 
                         { 
                                  back->right=move->left; 
                         }
                         free(move); 
                         return;