二叉搜索树的困难

时间:2017-01-22 20:06:46

标签: c binary-search-tree

作为练习的一部分,在努力学习编程时,我被要求创建一个使用的程序 结构 2.一个加倍的链表 3.二进制搜索树

创建客户数据库.. 我可以将节点添加到列表中并进行搜索。 但是,在尝试删除客户时,程序无法正常工作并崩溃。 我已经从第86行开始追踪问题到 BST_delete函数,因为如果我不运行此函数,程序运行得更好。 更详细地说,我认为我没有更新正确的 BST_email_root ,它应该是二进制树的最新节点。

这让我抓狂!我知道它不是最优雅的代码,但我仍在努力学习!感谢

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_STRING 250

void myflush();

// Defining a customer structure.
struct customer {
    char *name;
    char *address;
    char *email;
};

// A double linked list. The data field points to a customer struct.
struct double_linked_list {
    struct customer *data;
    struct double_linked_list *previous;
    struct double_linked_list *next;
};

// Defining a pointer for the first one of the customers in the double linked list.

struct double_linked_list *customers_head=0;

// A  node for a Binary Search Tree (BST).

struct BST_node {
    struct double_linked_list *data;
    struct BST_node *left;
    struct BST_node *right;
};

// Defining a variable for the root of the BST that is indexed by the email.
struct BST_node *BST_email_root = 0;

// Looking for a node with a specific email in the BST.

struct BST_node *BST_find_customer(struct BST_node *root, char *email) {
if (root==NULL)
    return NULL;
if (strcmp(email,root->data->data->email)==0)
    return root;
else
    {
    if (strcmp(email,root->data->data->email)==-1)
    return BST_find_customer(root->left,email);
    else
        return BST_find_customer(root->right,email);
    }
}

// A procedure to finding a customer according to his email.

void find_customer() {
    char email[MAX_STRING];
    struct double_linked_list *l;
    struct BST_node *b;
    printf("Give the email of the customer (up to %d characters) : ", MAX_STRING-1);
    gets(email);

    b = BST_find_customer(BST_email_root, email);
    if (b==0)
        printf("There is no customer with this email.\n");
    else
    {
        l = b->data;
        printf("Customer found! \n");
        printf("Name    : %s\n", l->data->name);
        printf("Address : %s\n", l->data->address);
        printf("Email   : %s\n", l->data->email);
    }
}

struct BST_node *findMaxNode(struct BST_node *root)
            {
                if(root->right == NULL) return root;
                findMaxNode(root->right);
            }

// Deleting a node in the BST, according to a given email.

// The function returns the (new?) root of the BST, which might have been changed or not.
struct BST_node *BST_delete(struct BST_node *root, char *email)
{

if (root==NULL)
    return root;
struct BST_node *father=NULL;
char which_son;
while (strcmp(email,root->data->data->email)!=0){ //first, finding root and remembering who's root father
if(root==NULL) {
     return root;
} else if (strcmp(email,root->data->data->email) <0){
     father = root;
     root = root->left;
     if(root==NULL)
        return;
     else which_son = 'l';
} else {
     father = root;
     root = root->right;
    if(root==NULL)
        return;
    else which_son = 'r';
}
}
// now you have both the root node, and its father
if ( (root->right == NULL) && (root->left == NULL) ){ //case 1, if it's a leaf
 free(root);

} else if (root->left == NULL) { //case 2
    if (which_son == 'l') {
        father->left = root->right;
    } else {
        father->right = root->right;
    }

} else { //case 3 : here i get the "rightest" son of root's left son
    struct BST_node *replacing_node = root->left;
    while (replacing_node->right != NULL) {
        replacing_node = replacing_node->right;
    } //now replacing_node is a leaf, and can replace root
    if (which_son == 'l') {
        father->left = replacing_node;
        replacing_node->left = root->left;
        replacing_node->right = root->right;
    } else {
        father->right = replacing_node;
        replacing_node->left = root->left;
        replacing_node->right = root->right;
    }
    }
    return root;
}


// This function adds a new node in the Binary Search Tree (BST) rooted by *root,

struct BST_node *new_BST_node(struct BST_node *root, struct double_linked_list *l)
    {
    if (root==NULL)
        {
        root= (struct BST_node *)malloc(sizeof(struct BST_node ));
        if (root==NULL)
            {
            printf("Out of Memory!");
            exit(1);
            }

        root->data=l;
        root->left=NULL;
        root->right=NULL;
        return root;
        }

    if ((strcmp(l->data->email,root->data->data->email))<0)
                root->left =new_BST_node(root->left,l);
    else
        root->right =new_BST_node(root->right,l);


    };


// A procedure to modify the data concerning an existing customer
void modify_customer() {
    char old_email[MAX_STRING];
    char new_email[MAX_STRING];
    char new_name[MAX_STRING];
    char new_address[MAX_STRING];
    char ans;

    struct BST_node *ind;
    struct double_linked_list *l;

    printf("Give the email of the customer you want to modify: ");
    gets(old_email);
    ind = BST_find_customer(BST_email_root, old_email);
    if (ind == 0)
    {
        printf("There is no customer with this email.\n");
        return;
    }

    l = ind->data;  // The node in the double linked list for the customer
    printf("Old name: %s\n", l->data->name);
    printf("Give the new name (up to %d characters, <Enter> if it does not change): ", MAX_STRING - 1);
    gets(new_name);
    if (new_name[0] == 0)
        strcpy(new_name, l->data->name);

    printf("Old address: %s\n", l->data->address);
    printf("Give the new address (up to %d characters, <Enter> if it does not change): ", MAX_STRING - 1);
    gets(new_address);
    if (new_address[0] == 0)
        strcpy(new_address, l->data->address);

    printf("Old email: %s\n", l->data->email);
    printf("Give the new email (up to %d characters, <Enter> if it does not change): ", MAX_STRING-1);
    gets(new_email);
    if (new_email[0] == 0)
        strcpy(new_email, l->data->email);

    if (strcmp(l->data->email, new_email))
    {
        if (BST_find_customer(BST_email_root, new_email))
        {
            printf("New email already exists. Modification aborted.\n");
            return;
        }
    }

    printf("\n\n");
    printf("REPLACE:\n");
    printf("Name    : %s\n", l->data->name);
    printf("Address : %s\n", l->data->address);
    printf("Email   : %s\n", l->data->email);
    printf("WITH:\n");
    printf("Name    : %s\n", new_name);
    printf("Address : %s\n", new_address);
    printf("Email   : %s\n\n", new_email);

    printf("Are you sure? (Y)es/(N)o\n");
    scanf(" %c", &ans);
    myflush();
    if (ans == 'Y' || ans == 'y')
    {
        free(l->data->name);
        l->data->name = strdup(new_name);
        free(l->data->address);
        l->data->address = strdup(new_address);

        if (strcmp(l->data->email, new_email) != 0)
            // Only in case the email has been changed, we have to maintain the BST
        {
            BST_email_root=BST_delete(BST_email_root, l->data->email);
            free(l->data->email);
            l->data->email = strdup(new_email);
            BST_email_root=new_BST_node(BST_email_root, l);
        }
    }
}

//  add a new customer
struct double_linked_list *new_customer()
{
    char name[MAX_STRING], address[MAX_STRING], email[MAX_STRING];
    struct BST_node *b;
    struct double_linked_list *l;
    struct customer *c;

    printf("\nADDING A CUSTOMER\n\n\n");
    printf("Give the name (up to %d characters): ", MAX_STRING-1);
    gets(name);

    printf("Give the address (up to %d characters): ", MAX_STRING - 1);
    gets(address);

    printf("Give the email (up to %d characters): ", MAX_STRING - 1);
    gets(email);

        // check for duplicate email
    b = BST_find_customer(BST_email_root, email);
    if (b)
    {
        printf("Duplicate email. Customer aborted.\n");
        return 0;
    }

    c = (struct customer *) malloc(sizeof(struct customer));
    if (c == 0)
    {
        printf("Not enough memory.\n");
        return 0;
    }

    c->name = strdup(name); // check for memory allocation problem
    if (c->name == 0) return 0;
    c->address = strdup(address);   // check for memory allocation problem
    if (c->address == 0) return 0;
    c->email = strdup(email);   // check for memory allocation problem
    if (c->email == 0) return 0;

    l = (struct double_linked_list*) malloc(sizeof(struct double_linked_list));
    if (l == 0)
    {
        printf("Not enough memory.\n");
        free(c->name);
        free(c->address);
        free(c->email);
        free(c);
        return 0;
    }

    l->data = c;
    l->previous = 0;
    l->next = customers_head;

    if (customers_head)
        customers_head->previous = l;

    customers_head = l;

    BST_email_root = new_BST_node(BST_email_root, l);

    return l;
}

// This function deletes a customer, based on its email
void delete_customer() {
    char email[MAX_STRING];
    struct BST_node *n_del;
    printf("Give the email of the customer you want to delete(up to %d characters) : ", MAX_STRING-1);
    gets(email);

    n_del = BST_find_customer(BST_email_root, email);
    if (n_del==0)
        printf("There is no customer with this email.\n");

    else
    {
    struct double_linked_list *current = n_del->data;
    //struct double_linked_list *temp;
    //struct double_linked_list *prev = customers_head;

    if (current->next==NULL &&current->previous==NULL)
        {
        free(current);
        customers_head=0;
        }

    else if (current->next==NULL) //TA EXOUN ANAPODA??i oxi..Den exw katalaveiNEXT=0 EINAI GIA TO PROTO STOIXEIO pou vazw. An exw mono ena stoixeio ti ginete? prepei na to dw..
        {
        printf("1");
        current->previous->next=NULL;
        free(current);
        }

    else if (current->previous==NULL)
        { printf("2");
            current->next->previous=NULL;   //Apla kane to previous tou proigoumenou apo ton teleytaio pou thes na kaneis na mi deixnei pouthena..
        customers_head=current->next;
        free(current);
        }
    else
       {
        printf("3");
        current->next->previous = current->previous;  //vle ton proigoumeno komvo na deixnei ston epomeno kai ton epomeno ston proigoumeno
        current->previous->next = current->next;      //Ftiakse to customer's head na deixnei sto proigoumeno pou einai pleon to pio prosfato sti lista
       }
    }

    BST_email_root=BST_delete(BST_email_root, email);
}


void displaymenu() {
    printf("\n\n");
    printf("1. New customer\n");
    printf("2. Find customer using email\n");
    printf("3. Modify customer\n");
    printf("4. Delete customer\n");
    printf("0. Exit\n\n");
    printf("Give a choice (0-6) : ");
}

// This function empties the buffer of the standard input (stdin), that is, of the keyboard
void myflush()
{
    char ch;
    while ((ch = getchar()) != '\n' && ch != EOF);
}


// The main function
int main() {
    int choice;
    do {
        displaymenu();
        scanf("%d", &choice);
        myflush();
        switch (choice) {
        case 1:
            new_customer();
            break;
        case 2:
            find_customer();
            break;
        case 3:
            modify_customer();
            break;
        case 4:
            delete_customer();
            break;

        default:
            printf("Wrong selection.\n\n");
        }
    } while (choice != 0);

    return 0;
}

3 个答案:

答案 0 :(得分:2)

如果不深入研究您的代码,我立刻就会看到一件事。你的陈述

-1

假设如果一个小于另一个,则返回值正好是strcmp。但是,在这种情况下,< 0的返回值仅保证为-1,而不是 $locations = array( array( 'location' => 'About', 'telephone' => '0121 34838383', 'email' => 'example@example.com' ) ); function telephone_shortcode() { global $locations; $title = get_the_title(); $key = array_search($title, array_column($locations, 'location')); if ($key) return $locations[$key]['telephone']; else return 'fail'; } add_shortcode('telephone', 'telephone_shortcode'); (参见strcmp reference)。

因此,在搜索&#34;父亲&#34;时,您可能找不到您要查找的节点...

答案 1 :(得分:1)

这是我修改过的版本。我认为不需要double_linked_list。您可以直接将客户用于BST_node.data。我测试了添加新客户,找到客户,删除客户,所有工作都按预期工作。但我没有测试修改客户,我觉得这很简单。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_STRING 250

void myflush();

// Defining a customer structure.
struct customer {
    char *name;
    char *address;
    char *email;
};

// A double linked list. The data field points to a customer struct.
struct double_linked_list {
    struct customer *data;
    struct double_linked_list *previous;
    struct double_linked_list *next;
};

// Defining a pointer for the first one of the customers in the double linked list.

struct double_linked_list *customers_head=0;

// A  node for a Binary Search Tree (BST).

struct BST_node {
    struct double_linked_list *data;
    struct BST_node *top;
    struct BST_node *left;
    struct BST_node *right;
};

// Defining a variable for the root of the BST that is indexed by the email.
struct BST_node *BST_email_root = 0;

// Looking for a node with a specific email in the BST.

struct BST_node *BST_find_customer(struct BST_node *root, char *email) {
if (root==NULL)
    return NULL;

int rv = strcmp(email,root->data->data->email);

if (rv==0)
    return root;
else
    {
    if (rv<0)
    return BST_find_customer(root->left,email);
    else
        return BST_find_customer(root->right,email);
    }
}

// A procedure to finding a customer according to his email.

void find_customer() {
    char email[MAX_STRING];
    struct double_linked_list *l;
    struct BST_node *b;
    printf("Give the email of the customer (up to %d characters) : ", MAX_STRING-1);
    gets(email);

    b = BST_find_customer(BST_email_root, email);
    if (b==0)
        printf("There is no customer with this email.\n");
    else
    {
        l = b->data;
        printf("Customer found! \n");
        printf("Name    : %s\n", l->data->name);
        printf("Address : %s\n", l->data->address);
        printf("Email   : %s\n", l->data->email);
    }
}

struct BST_node *findMaxNode(struct BST_node *root)
            {
                if(root->right == NULL) return root;
                findMaxNode(root->right);
                return NULL;
            }

// Deleting a node in the BST, according to a given email.

// The function returns the (new?) root of the BST, which might have been changed or not.
struct BST_node *BST_delete(struct BST_node *root, char *email)
    {

    if (root==NULL)
        return root;
    struct BST_node *father=NULL;
    char which_son;
    while (strcmp(email,root->data->data->email)!=0){ //first, finding root and remembering who's root father
    if(root==NULL) {
         return NULL;
    } else if (strcmp(email,root->data->data->email) < 0){
         father = root;
         root = root->left;
         which_son = 'l';
    } else {
         father = root;
         root = root->right;
         which_son = 'r';
    }
}
    // now you have both the root node, and its father
    if ( (root->right == NULL) && (root->left == NULL) ){ //case 1, if it's a leaf
     free(root);

    } else if (root->left == NULL) { //case 2
        if (which_son == 'l') {
            father->left = root->right;
        } else {
            father->right = root->right;
        }

    } else { //case 3 : here i get the "rightest" son of root's left son
        struct BST_node *replacing_node = root->left;
        while (replacing_node->right != NULL) {
            replacing_node = replacing_node->right;
        } //now replacing_node is a leaf, and can replace root
        if (which_son == 'l') {
            father->left = replacing_node;
            replacing_node->left = root->left;
            replacing_node->right = root->right;
        } else {
            father->right = replacing_node;
            replacing_node->left = root->left;
            replacing_node->right = root->right;
        }
        }
        return root;
    }


// This function adds a new node in the Binary Search Tree (BST) rooted by *root,

void new_BST_node(struct BST_node *root, struct double_linked_list *l)
{
    if ((strcmp(l->data->email,root->data->data->email))<0)
    {
        if(root->left == NULL)
        {
            root->left = (struct BST_node *)malloc(sizeof(struct BST_node ));
            root->left->data = l;
            root->left->top = root;
            root->left->left = NULL;
            root->left->right = NULL;
        }
        else
        {
            new_BST_node(root->left,l);
        }
    }
    else
    {
        if(root->right == NULL)
        {
            root->right = (struct BST_node *)malloc(sizeof(struct BST_node ));
            root->right->data = l;
            root->right->top = root;
            root->right->left = NULL;
            root->right->right = NULL;
        }
        else
        {
            new_BST_node(root->right,l);
        }
    }
}


// A procedure to modify the data concerning an existing customer
void modify_customer() {
    char old_email[MAX_STRING];
    char new_email[MAX_STRING];
    char new_name[MAX_STRING];
    char new_address[MAX_STRING];
    char ans;

    struct BST_node *ind;
    struct double_linked_list *l;

    printf("Give the email of the customer you want to modify: ");
    gets(old_email);
    ind = BST_find_customer(BST_email_root, old_email);
    if (ind == 0)
    {
        printf("There is no customer with this email.\n");
        return;
    }

    l = ind->data;  // The node in the double linked list for the customer
    printf("Old name: %s\n", l->data->name);
    printf("Give the new name (up to %d characters, <Enter> if it does not change): ", MAX_STRING - 1);
    gets(new_name);
    if (new_name[0] == 0)
        strcpy(new_name, l->data->name);

    printf("Old address: %s\n", l->data->address);
    printf("Give the new address (up to %d characters, <Enter> if it does not change): ", MAX_STRING - 1);
    gets(new_address);
    if (new_address[0] == 0)
        strcpy(new_address, l->data->address);

    printf("Old email: %s\n", l->data->email);
    printf("Give the new email (up to %d characters, <Enter> if it does not change): ", MAX_STRING-1);
    gets(new_email);
    if (new_email[0] == 0)
        strcpy(new_email, l->data->email);

    if (strcmp(l->data->email, new_email))
    {
        if (BST_find_customer(BST_email_root, new_email))
        {
            printf("New email already exists. Modification aborted.\n");
            return;
        }
    }

    printf("\n\n");
    printf("REPLACE:\n");
    printf("Name    : %s\n", l->data->name);
    printf("Address : %s\n", l->data->address);
    printf("Email   : %s\n", l->data->email);
    printf("WITH:\n");
    printf("Name    : %s\n", new_name);
    printf("Address : %s\n", new_address);
    printf("Email   : %s\n\n", new_email);

    printf("Are you sure? (Y)es/(N)o\n");
    scanf(" %c", &ans);
    myflush();
    if (ans == 'Y' || ans == 'y')
    {
        free(l->data->name);
        l->data->name = strdup(new_name);
        free(l->data->address);
        l->data->address = strdup(new_address);

        if (strcmp(l->data->email, new_email) != 0)
            // Only in case the email has been changed, we have to maintain the BST
        {
            BST_email_root=BST_delete(BST_email_root, l->data->email);
            free(l->data->email);
            l->data->email = strdup(new_email);
            new_BST_node(BST_email_root, l);
        }
    }
}

//  add a new customer
struct double_linked_list *new_customer()
{
    char name[MAX_STRING], address[MAX_STRING], email[MAX_STRING];
    struct BST_node *b;
    struct double_linked_list *l;
    struct customer *c;

    printf("\nADDING A CUSTOMER\n\n\n");
    printf("Give the name (up to %d characters): ", MAX_STRING-1);
    gets(name);

    printf("Give the address (up to %d characters): ", MAX_STRING - 1);
    gets(address);

    printf("Give the email (up to %d characters): ", MAX_STRING - 1);
    gets(email);

        // check for duplicate email
    b = BST_find_customer(BST_email_root, email);
    if (b)
    {
        printf("Duplicate email. Customer aborted.\n");
        return 0;
    }

    c = (struct customer *) malloc(sizeof(struct customer));
    if (c == 0)
    {
        printf("Not enough memory.\n");
        return 0;
    }

    c->name = strdup(name); // check for memory allocation problem
    if (c->name == 0) return 0;
    c->address = strdup(address);   // check for memory allocation problem
    if (c->address == 0) return 0;
    c->email = strdup(email);   // check for memory allocation problem
    if (c->email == 0) return 0;

    l = (struct double_linked_list*) malloc(sizeof(struct double_linked_list));
    if (l == 0)
    {
        printf("Not enough memory.\n");
        free(c->name);
        free(c->address);
        free(c->email);
        free(c);
        return 0;
    }

    l->data = c;
    l->previous = 0;
    l->next = customers_head;

    if (customers_head)
        customers_head->previous = l;

    customers_head = l;

    if (BST_email_root==NULL)
    {
        BST_email_root = (struct BST_node *)malloc(sizeof(struct BST_node ));

        BST_email_root->data = l;
        BST_email_root->top = NULL;
        BST_email_root->left = NULL;
        BST_email_root->right = NULL;
    }
    else
    {
      new_BST_node(BST_email_root, l);
    }

    return l;
}

void print_customers(struct BST_node *node)
{
    if(node == NULL)
    {
        printf("No customers yet\n");
    }
    else if(node->left)
    {
        print_customers(node->left);
        printf("%s %s %s\n", node->data->data->name,
                             node->data->data->address,
                             node->data->data->email);
        if(node->right)
        {
            print_customers(node->right);
        }
    }
    else if(node->right)
    {
        printf("%s %s %s\n", node->data->data->name,
                             node->data->data->address,
                             node->data->data->email);
        print_customers(node->right);
    }
    else
    {
        printf("%s %s %s\n", node->data->data->name,
                             node->data->data->address,
                             node->data->data->email);
    }
}

// This function deletes a customer, based on its email
void delete_customer() {
    char email[MAX_STRING];
    struct BST_node *n_del;
    printf("Give the email of the customer you want to delete(up to %d characters) : ", MAX_STRING-1);
    gets(email);

    n_del = BST_find_customer(BST_email_root, email);
    if (n_del==0)
        printf("There is no customer with this email.\n");

    else
    {
        if(n_del->left && n_del->right)
        {
           if(n_del->top->left == n_del)
           {
                n_del->top->left = n_del->left;
           }
           else
           {
                n_del->top->right = n_del->left;
           }

           struct BST_node *node = n_del->left;
           while(node->right)
           {
              node = node->right;
           }
           node->right = n_del->right;
        }
        else if(n_del->left)
        {
           if(n_del->top->left == n_del)
           {
               n_del->top->left = n_del->left;
           }
           else  // must be right node
           {
               n_del->top->right = n_del->left; 
           }
        }
        else if(n_del->right)
        {
           if(n_del->top->left == n_del)
           {
               n_del->top->left = n_del->right;
           }
           else  // must be right node
           {
               n_del->top->right = n_del->right; 
           }
        }
        else {   /* a leaf */
           if(n_del->top->left == n_del)
           {
               n_del->top->left = NULL; 
           }
           else  // must be right node
           {
               n_del->top->right = NULL; 
           }
        }

        free(n_del->data->data->name);
        free(n_del->data->data->email);
        free(n_del->data->data->address);
        free(n_del->data->data);
        free(n_del->data);
        free(n_del);
    }

}


void displaymenu() {
    printf("\n\n");
    printf("1. New customer\n");
    printf("2. Find customer using email\n");
    printf("3. Modify customer\n");
    printf("4. Delete customer\n");
    printf("5. List customers\n");
    printf("0. Exit\n\n");
    printf("Give a choice (0-5) : ");
}

// This function empties the buffer of the standard input (stdin), that is, of the keyboard
void myflush()
{
    char ch;
    while ((ch = getchar()) != '\n' && ch != EOF);
}


// The main function
int main() {
    int choice;
    do {
        displaymenu();
        scanf("%d", &choice);
        myflush();
        switch (choice) {
        case 1:
            new_customer();
            break;
        case 2:
            find_customer();
            break;
        case 3:
            modify_customer();
            break;
        case 4:
            delete_customer();
            break;
        case 5:
            print_customers(BST_email_root);
            break;

        default:
            printf("Wrong selection.\n\n");
        }
    } while (choice != 0);

    return 0;
}

答案 2 :(得分:1)

在测试提供的源代码并插入@StephanLechner的注释后,主要问题是由于BST_find_customer()算法与使用的算法之间存在差距,BST_find_customer()无法找到任何节点。 new_BST_node()

错误1 - 在BST_find_customer()函数中,在查找左或右节点之前,请浏览root->data(a struct double_linked_list *)。

// explore the list from root->data;
struct double_linked_list *ldata = root->data;
while (ldata!=NULL) {
    if (strcmp(email,ldata->data->email)==0) {
        return (root);
    }
    ldata=ldata->next;
}
if (strcmp(email,root->data->data->email)<0) { // ERROR ==-1) {
    return BST_find_customer(root->left,email);
}
else {
    return BST_find_customer(root->right,email);
}

而不是:

if (strcmp(email,root->data->data->email)==0)
    return root;
else {
    if (strcmp(email,root->data->data->email)==-1)
        return BST_find_customer(root->left,email);
    else
        return BST_find_customer(root->right,email);
}

错误2 - 在BST_delete()函数中,在浏览root之前检查data的有效性。

  

在while循环中添加if-condition (root!=NULL)以防止   最终的树。

     

该函数应返回值return (NULL);而不是   return;,否则未定义的行为。

while ((root!=NULL) && (strcmp(email,root->data->data->email)!=0)){ 
    if (strcmp(email,root->data->data->email) < 0){
         father = root;
         root = root->left;
         which_son = 'l';
    } else {
         father = root;
         root = root->right;
         which_son = 'r';
    }
}
if(root==NULL) {
     return (root);
}

而不是:

while (strcmp(email,root->data->data->email)!=0) { //first, finding root and remembering who's root father
    if(root==NULL) {
         return root;
    } else if (strcmp(email,root->data->data->email) <0){
         father = root;
         root = root->left;
         if(root==NULL)
            return;
         else which_son = 'l';
    } else {
         father = root;
         root = root->right;
        if(root==NULL)
            return;
        else which_son = 'r';
    }
}

错误3 - 在delete_customer()中,当没有客户输入电子邮件时,中止删除。

n_del = BST_find_customer(BST_email_root, email);
if (n_del==0) {
    printf("There is no customer with this email.\n");
    return;
}
else

而不是:

n_del = BST_find_customer(BST_email_root, email);
if (n_del==0)
    printf("There is no customer with this email.\n");
    // ABORT HERE
else