二叉搜索树“删除”功能

时间:2013-08-08 17:00:05

标签: c++ c binary-search-tree

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

我的麻烦主要源于这样一个事实,一旦我找到需要删除的节点,我需要在需要删除的节点之后将它的PARENT节点设置为节点。我应该使用游标来保留父节点吗?

我有节点的结构:

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

remove函数的定义如下:

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

感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

简单的方法是扩展搜索代码,以便在沿树向下移动时跟踪第二个引用中的“最后”父级。然后,这个“扩展”搜索返回节点和节点的父节点。

然后您通过删除功能使用该搜索功能,因此您不必在删除逻辑中执行任何花哨的操作。

答案 1 :(得分:0)

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

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

结构声明:

 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 :对不起,我刚注意到你的功能的原型声明。我希望更改此代码以匹配您的原型声明应该不会太困难。

答案 2 :(得分:0)

你可以试试这个:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Address = "$AB$12:$AD$13" Then
        Range("B1").Copy
        Range("E11").Copy
        Sheets("Data").Range("B" & lastrow).PasteSpecial xlPasteValues
    End If
End Sub