简体   繁体   English

如何在C中实现没有递归的二叉搜索树的删除功能?

[英]How to implement the function delete of a binary search tree without recursion in C?

I try to implement the delete method but that doesn't work with me.我尝试实现删除方法,但这对我不起作用。 I want to delete all nodes in the tree. 我想删除树中的所有节点。 The function has tree type of "struct tree" as a parameter so I can't use recursion;该函数将“struct tree”的树类型作为参数,所以我不能使用递归; I want to do it with a loop.我想用循环来做。

That's my structure这是我的结构

    typedef struct Node Node;
    struct Node{
        const void* data;
        const void* value; 
        Node* left;
        Node* right;
    };

    typedef struct Tree Tree;
    struct Tree{
        Node* root;
        size_t size;
        int (*comp)(const void *, const void *);
    };

function delete函数删除

    void freeTree(Tree* tree, bool TreeContent){
        if(tree->root != NULL){

            // free(tree->root->left);
            // free(tree->root->right);
            // free(tree->root);
        }
    }              

function insert函数插入

bool insertInTree(Tree* bst, const void* key, const void* value){
    if(bst->root == NULL){
            Node* newNode = (Node*) malloc(sizeof(Node));
            if(newNode == NULL){
                   printf("erreur d'allocation dynamique \n");
                   exit(1);
            }
            newNode->left =  newNode->right = NULL;
            newNode->value = value;
            newNode->data = key;
            return true;
    }
    else{
            int isLeft = 0 ;
            Node* Current = bst->root ;
            Node* precedant = NULL;
            while(Current != NULL){
                int compare = bst->comp(&Current->data , &key);
                precedant = Current;
            if(compare == 1){
                   isLeft = 1;
                   Current = Current->left;
            }
            else if(compare == 0){
                    isLeft = 0;
                    Current = Current->right;
            }

            }
            if(isLeft == 1){
                    Node* newNode = (Node*) malloc(sizeof(Node));
                    if(newNode == NULL){
                                       printf("erreur d'allocation dynamique \n");
                                       exit(1);
                    }
                    newNode->left =  newNode->right = NULL;
                    newNode->value = value;
                    newNode->data = key;
                    precedant->left = newNode;
                    bst->size++;
                    return true;
                    }
            else{
                    Node* newNode = (Node*) malloc(sizeof(Node));
                    if(newNode == NULL){
                                       printf("erreur d'allocation dynamique \n");
                                       exit(1);
                    }

                    newNode->left =  newNode->right = NULL;
                    newNode->value = value;
                    newNode->data = key;
                    precedant->right = newNode;
                    bst->size++;
                    return true;

            }

        }
        return false;
}

edit You don't want to use recursion because the freeTree function doesn't take a Node argument.编辑您不想使用递归,因为freeTree函数不接受Node参数。 In this case, you can remove that restriction by creating another function that is recursive, called initially by freeTree .在这种情况下,您可以通过创建另一个递归函数来消除该限制,该函数最初由freeTree

void freeTree(Tree* tree, bool TreeContent){
    if(tree->root != NULL){
        freeNode(tree->root);
        tree->root = NULL;
    }
}            

The new freeNode could look like新的freeNode可能看起来像

void freeNode(Node *node) {
    if (node->left) freeNode(node->left);
    if (node->right) freeNode(node->right);
    free(node);
}

Note that freeNode intent is to free the whole tree (otherwise the parent element's left or right [or root] would have to be set to NULL).请注意, freeNode意图是释放整个树(否则父元素的左或右 [或根] 必须设置为 NULL)。

Your requirement is that you don't want to use recursion.您的要求是您不想使用递归。

Any kind of traversal is not possible in O(n) time without use of a stack/queue (implicitly or explicitly).在不使用堆栈/队列(隐式或显式)的情况下,任何类型的遍历都不可能在O(n)时间内进行。 So we will use a stack (made using an array) and use it to delete all the nodes.所以我们将使用一个堆栈(使用数组制作)并使用它来删除所有节点。

I understand that you have the size of the BST known, so you can create an array of appropriate size as -我知道您知道 BST 的大小,因此您可以创建一个适当大小的数组作为 -

struct Node* stack[bst->size];
int top = -1;

This stack will hold all the elements to be processed.这个堆栈将保存所有要处理的元素。

We will first add the root to the stack -我们将首先将根添加到堆栈中 -

if(bst->root)
    stack[++top] = bst->root;

Now we need to process all the nodes in the tree using a loop -现在我们需要使用循环处理树中的所有节点 -

while(top>=0){
    //Pop one node - 
    struct Node* node = stack[top--];
    //Add its children to the stack;
    if(node->left)
        stack[++top] = node->left;
    if(node->right)
        stack[++top] = node->right;
    // Now free the node as 
    free(node);
}

That is all, one by one each node will be added to the stack and the stack will become empty when all the nodes are done.就是这样,每个节点将一个一个地添加到堆栈中,当所有节点都完成时,堆栈将变为空。

Also as a side note, in your insert function you need to do bst->size++ in the if(bst->root == NULL) branch.另外作为旁注,在您的插入函数中,您需要在if(bst->root == NULL)分支中执行bst->size++ Else your size will be one less than actual number of nodes.否则您的大小将比实际节点数少一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM