【问题标题】:Deletion on Balancing Binary Tree删除平衡二叉树
【发布时间】:2020-04-25 08:28:56
【问题描述】:

我有一个用于将数据插入平衡二叉树的代码,所以示例是,如果我输入这些输入:

20, 10, 30, 5, 15, 25, 4

我希望输入后的树看起来像这样:

         20
     /        \
    10        30
   /  \     /    \
  5   15   25     4

所以,删除时,除了删除 4 之外,一切正常
4属于删除功能中的案例1,
问题是,我不明白为什么删除4不起作用,但是当我删除5、15、25时,它起作用了?


我从https://www.youtube.com/watch?v=gcULXE7ViZw 获得了删除功能
它是用于二叉搜索树的,但我认为即使在二叉树中使用它也不会造成问题

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<conio.h>

struct node{

    int data, balance;

    struct node *left, *right;

};

int insert(struct node **root, struct node **curr, int data){

    struct node *newNode = (struct node*)malloc(sizeof(struct node));
    newNode -> data = data;
    newNode -> left = NULL;
    newNode -> right = NULL;
    newNode -> balance = 0;

    if((*root) == NULL){
        (*root) = (*curr) = newNode;
        (*root) -> left = NULL;
        (*root) -> right = NULL;
        return 0;
    } else {
        if((*curr)->left == NULL && (*curr)->balance == 0){
            (*curr) -> balance = (*curr) -> balance - 1;
            (*curr) -> left = newNode;
            return 0;
        } else if ((*curr)->right == NULL && (*curr)->balance == -1){
            (*curr) -> balance = (*curr) -> balance + 1;
            (*curr) -> right = newNode;
            return 0;
        } else if ((*curr)->balance == 0 && (*curr)->left->balance == 0){
            (*curr) -> balance = (*curr) -> balance - 1;
            (*curr) = (*curr)->left;
            return insert(root,curr,data);
        } else if ((*curr)->balance < 0 && (*curr)->left->balance < 0){
            (*curr) -> balance = (*curr) -> balance - 1;
            (*curr) = (*curr) -> left;
            return insert(root,curr,data);
        } else if ((*curr)->balance < 0 && (*curr)->left->balance == 0){
            (*curr) -> balance = (*curr) -> balance + 1;
            (*curr) = (*curr)->right;
            return insert(root, curr, data);
        }
    }
}

void preorder(struct node *root){

    if(root == NULL) return;
    printf("%d ", root->data);
    preorder(root->left);
    preorder(root->right);

}

void postorder(struct node *root){

    if(root == NULL) return;
    postorder(root->left);
    postorder(root->right);
    printf("%d ", root->data);

}

void inorder(struct node *root){

    if(root == NULL) return;
    inorder(root->left);
    printf("%d ", root->data);
    inorder(root->right);

}

void search(struct node *root, int *key, int *found){

    if(root == NULL) return;
    search(root->left, key, found);
    if(root->data == *key){
        *found = 1;
        return ;
    }
    search(root->right, key, found);

}

struct node *findMin(struct node *root){

    while(root->left != NULL) root = root->left;
    return root;
}

struct node *Delete(struct node *root, int data){

    if(root == NULL) return root;
    else if(data < root->data) root->left = Delete(root->left, data);
    else if(data > root->data) root->right = Delete(root->right, data);
    else {
        //Case 1: no child / leaf node
        if(root->left == NULL && root->right == NULL){
            free(root);
            root = NULL;
        }
        //Case 2: one child, left or right
        else if(root->left == NULL){
            struct node *temp = root;
            root = root->right;
            free(temp);
        } else if (root->right == NULL){
            struct node *temp = root;
            root = root->left;
            free(temp);
        }
        //Case 3: two children
        else{
            struct node *temp = findMin(root->right);
            root->data = temp->data;
            root->right = Delete(root->right, temp->data);
        }
    }
    return root;
}


int main(){

    struct node *root, *curr;
    int choice, data, key, found, delKey;
    root = curr = NULL;

    while(1){
        found = 0;
        printf("Balanced Binary Tree Menu\n");
        printf("1. Insert Data\n");
        printf("2. View on pre order\n");
        printf("3. View on post order\n");
        printf("4. View on in order\n");
        printf("5. Search\n");
        printf("6. Delete\n");
        printf("7. Exit\n");
        printf("Pilihan: ");scanf("%d", &choice);fflush(stdin);

        if(choice == 1){
            printf("Enter data : "); scanf("%d", &data);
            curr = root;
            insert(&root, &curr, data);
        } else if (choice == 2){
            preorder(root);
            system("pause");
        } else if (choice == 3){
            postorder(root);
            system("pause");
        } else if (choice == 4){
            inorder(root);
            system("pause");
        } else if (choice == 5){
            printf("Search: "); scanf("%d", &key);
            search(root, &key, &found);
            if(found == 1){
                printf("Data found !\n");
            } else {
                printf("Data not found !\n");
            }
            system("pause");
        } else if (choice == 6){
            curr = root;
            printf("Data : ");
            preorder(root);
            printf("\n\n");
            printf("Enter data to be deleted: "); scanf("%d", &delKey);
            Delete(curr, delKey);
            printf("Data after deletion : ");
            preorder(root);
            system("pause");

        } else if (choice == 7){
            return 1;
        }
        system("cls");
    }

    return 0;
}

【问题讨论】:

  • 在 20, 10, 30, 5, 15, 4 中没有 25,怎么会在生成的树中? insert 并非在所有情况下都返回值。更改删除平衡树必须保持平衡,如果您使用其他算法则不会。如果您按 20、10、30、5、15 和 4 的顺序插入并按顺序查看结果是“5 10 15 20 4 30”,这已经是错误的,问题不仅在删除部分
  • @bruno 哦,我忘了写 25 输入,我要编辑代码。顺序结果不是左-亲-右,所以打印的是正确的结果吗?
  • 你有前后顺序,似乎合乎逻辑的“按顺序”会产生没有排序的值?
  • 我本来打算只根据树打印数据,所以数据实际上不应该排序。
  • 如果不是这种情况,假设数据在树中排序,你怎么能删除?

标签: c struct binary-tree


【解决方案1】:

问题在于删除功能。您将删除作为二叉搜索树执行。因此,从根节点(在您的示例中为 20),它继续在左子节点中搜索 4。 所以代码从 20 开始,到 10,然后是 5,然后因为找不到 4 而停止。

因此您需要更改删除中的搜索策略(一个中序、后序、预序或水平序遍历)。请记住,您的树不是二叉搜索树。它只是平衡的。所以要删除的时候需要查看每个节点。

【讨论】:

  • 您好@Shobhit Kumar 我尝试使用中序遍历,并找到了数据所在的根。但是当它试图从我的示例中删除 4 时,它会显示结果: 25 10 5 15 4 25 。你能解释一下当我想删除时如何查看每个节点吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-13
  • 2018-08-30
  • 1970-01-01
  • 1970-01-01
  • 2015-01-08
相关资源
最近更新 更多