C 关于平衡二叉树的删除

C 关于平衡二叉树的删除,c,struct,binary-tree,C,Struct,Binary Tree,我有一个将数据插入平衡二叉树的代码,因此示例是,如果我输入以下输入: 20, 10, 30, 5, 15, 25, 4 我希望输入后的树如下所示: 20 / \ 10 30 / \ / \ 5 15 25 4 因此,在删除时,除了删除4之外,所有操作都正常运行 4属于删除功能中的情况1, 问题是,我不明白为什么删除4不起作用,但当我删除5、15、25时,它起作用了吗 我从 它是用于二

我有一个将数据插入平衡二叉树的代码,因此示例是,如果我输入以下输入:

20, 10, 30, 5, 15, 25, 4
我希望输入后的树如下所示:

         20
     /        \
    10        30
   /  \     /    \
  5   15   25     4
因此,在删除时,除了删除4之外,所有操作都正常运行
4属于删除功能中的情况1,
问题是,我不明白为什么删除4不起作用,但当我删除5、15、25时,它起作用了吗


我从
它是用于二叉搜索树的,但我认为即使在二叉树中使用它也不会引起任何问题

#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;
}

#包括
#包括
#包括
#包括
结构节点{
int数据,平衡;
结构节点*左、*右;
};
整数插入(结构节点**根,结构节点**当前,整数数据){
结构节点*新节点=(结构节点*)malloc(sizeof(结构节点));
新建节点->数据=数据;
newNode->left=NULL;
newNode->right=NULL;
新建节点->余额=0;
if((*root)==NULL){
(*root)=(*curr)=新节点;
(*root)->left=NULL;
(*root)->right=NULL;
返回0;
}否则{
如果((*curr)->left==NULL&(*curr)->balance==0){
(*货币)->余额=(*货币)->余额-1;
(*curr)->左=新节点;
返回0;
}如果((*curr)->right==NULL&(*curr)->balance==1,则为else{
(*本币)->余额=(*本币)->余额+1;
(*curr)->right=newNode;
返回0;
}如果((*curr)->余额==0&&(*curr)->左->余额==0,则为else{
(*货币)->余额=(*货币)->余额-1;
(*curr)=(*curr)->左;
返回插入(根、当前、数据);
}如果((*当前)->余额<0&(*当前)->左侧->余额<0,则为else{
(*货币)->余额=(*货币)->余额-1;
(*curr)=(*curr)->左;
返回插入(根、当前、数据);
}如果((*curr)->余额<0&(*curr)->左->余额==0,则为else{
(*本币)->余额=(*本币)->余额+1;
(*curr)=(*curr)->对;
返回插入(根、当前、数据);
}
}
}
无效预订单(结构节点*根){
if(root==NULL)返回;
printf(“%d”,根->数据);
预订单(根->左);
预订单(根->右);
}
作废后订单(结构节点*根){
if(root==NULL)返回;
后订单(根->左);
后订单(根->右);
printf(“%d”,根->数据);
}
无效索引顺序(结构节点*根){
if(root==NULL)返回;
顺序(根->左);
printf(“%d”,根->数据);
顺序(根->右);
}
无效搜索(结构节点*根,int*键,int*已找到){
if(root==NULL)返回;
搜索(根->左,键,已找到);
如果(根->数据==*键){
*发现=1;
返回;
}
搜索(root->right,key,found);
}
结构节点*findMin(结构节点*根){
而(root->left!=NULL)root=root->left;
返回根;
}
结构节点*删除(结构节点*根,int数据){
if(root==NULL)返回root;
如果(数据<根->数据)根->左=删除(根->左,数据);
否则如果(数据>根->数据)根->右=删除(根->右,数据);
否则{
//案例1:没有子节点/叶节点
if(root->left==NULL&&root->right==NULL){
自由根;
root=NULL;
}
//案例2:一个孩子,左或右
else if(root->left==NULL){
结构节点*temp=root;
根=根->右;
免费(临时);
}else if(root->right==NULL){
结构节点*temp=root;
根=根->左;
免费(临时);
}
//案例3:两名儿童
否则{
结构节点*temp=findMin(根->右);
根->数据=临时->数据;
根->右=删除(根->右,临时->数据);
}
}
返回根;
}
int main(){
结构节点*root,*curr;
int-choice,数据,键,find,delKey;
root=curr=NULL;
而(1){
发现=0;
printf(“平衡二叉树菜单”);
printf(“1.插入数据\n”);
printf(“2.预订单视图\n”);
printf(“3.邮购查看\n”);
printf(“4.按顺序查看\n”);
printf(“5.Search\n”);
printf(“6.删除\n”);
printf(“7.退出\n”);
printf(“Pilihan:”);scanf(“%d”,&choice);fflush(stdin);
如果(选项==1){
printf(“输入数据:”;scanf(“%d”和“数据”);
curr=根;
插入(&root,&curr,data);
}else if(选项==2){
前序(根);
系统(“暂停”);
}else if(选项==3){
后序(根);
系统(“暂停”);
}else if(选项==4){
顺序(根);
系统(“暂停”);
}else if(选项==5){
printf(“搜索:”;scanf(“%d”,&key);
搜索(根目录、键和找到的键);
如果(找到==1){
printf(“找到数据!\n”);
}否则{
printf(“未找到数据!\n”);
}
系统(“暂停”);
}else if(选项==6){
curr=根;
printf(“数据:”);
前序(根);
printf(“\n\n”);
printf(“输入要删除的数据:”;scanf(“%d”)和delKey);
删除(curr、delKey);
printf(“删除后的数据:”);
前序(根);
系统(“暂停”);
}else if(选项==7){
返回1;
}
系统(“cls”);
}
返回0;
}

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

因此,您需要在delete中更改搜索策略(按顺序、按顺序、按顺序或按级别遍历)。记住你的树不是二进制的