LuqTozaki
LuqTozaki

Reputation: 7

Search Binary Tree received when Search is wrong

Guys I really cannot handle. How am i supposed to solve this. I kept getting my root error it always mention that root is nullptr. Then, suddenly all my record of books gone/remove. I don't know how to manage this problem i kept changing using strcmp and without it but still. Same goes if I found the searched, it delete all my record of the books. Maybe you guys can provide me some error syntax that need to be fix and explaination of my error through coding. This is the snapshot of the error

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct node{
    char title[50], author[50], ISBN[50], pubDate[20], searchAuthor[50];
    struct node* left, * right;
};
struct node* delete_node(struct node* root, char deleteAuthor[]);
struct node* insert_node(struct node* root, char author[], char title[], char ISBN[], char pubDate[]);
struct node* FindMin(struct node*);
//struct node* search(struct node* root, char deleteAuthor[]);

void in_display(struct node* root);
void search(struct node* root, char searchAuthor[]);


void main()
{
    struct node* root = NULL;
    int ch, loop;
    char title[50], author[50], ISBN[50], pubDate[20], searchAuthor[50], deleteAuthor[50];
    printf("\n\n\t\t\tBinary Search Tree");
    printf("\n\t\t-- To stores a library of book records");
    printf("\n\t\t-- To search a library of book records");
    printf("\n\t\t-- To delete a library of book records");
    printf("\n\t\t-- To display a library of book records");
    printf("\n\t=========================================================\n");

    printf("\n\tState the number of book you need to input: ");
    scanf("%d", &loop);
    for (int c = 0; c < loop; c++) {
        printf("\n\n\t\t\t--------Insert New Book--------");
        printf("\n\tEnter the author of the book: \t\t\t");
        scanf("\n%[^\n]%*c", author);
        printf("\tEnter the title of the book: \t\t\t");
        scanf("\n%[^\n]%*c", title);
        printf("\tKey in the ISBN code: \t\t\t\t");
        scanf("\n%[^\n]%*c", ISBN);
        printf("\tEnter the Publication Date of the book: \t");
        scanf("\n%[^\n]%*c", pubDate);
        root = insert_node(root, author, title, ISBN, pubDate);
    }
    printf("\t\t\t--------Insert New Book End--------\n\n");
    printf("\n\tPlease enter choice (1/2/3/4/5) based on the ....");
    do
    {
        //printf("\n\t1.\tInsert a new Boook Record");
        printf("\n\t1.\tDisplay all the Books record");
        printf("\n\t2.\tDelete a Book Record");
        printf("\n\t3.\tSearch a abook Record ");
        printf("\n\t4.\tExit");
        printf("\n\n\tEnter your choice: ");
        scanf("%d", &ch);
        switch (ch){
        case 1:
            printf("\n\t\t-----------------Library of Book Records-----------------\n");
            in_display(root);
            break;
        case 2:
            printf("\nEnter the author of the book to be deleted: \t");
            scanf("\n%[^\n]%*c", deleteAuthor);
            root = delete_node(root, deleteAuthor);
            break;
        case 3:
            printf("\nEnter the author of the book to be searched: \t");
            scanf("\n%[^\n]%*c", searchAuthor);
            search(root, searchAuthor);
            break;
        case 4:
            exit(0);
            break;
        default: printf("\n\tWrong Option\n");
        }
    } while (1);
}
struct node* insert_node(struct node* root, char author[], char title[], char ISBN[], char pubDate[])
{
    if (root == NULL)
    {
        struct node* temp = (struct node*)malloc(sizeof(struct node));
        strcpy(temp->author, author);
        strcpy(temp->title, title);
        strcpy(temp->ISBN, ISBN);
        strcpy(temp->pubDate, pubDate);
        temp->left = NULL;
        temp->right = NULL;
        return temp;
    }
    if (strcmp(author, root->author)<=0)
    {
        root->left = insert_node(root->left, author, title, ISBN, pubDate);
    }
    else
    {
        root->right = insert_node(root->right, author, title, ISBN, pubDate);
    }
    return root;
}
void in_display(struct node* root) {
    
    if (root == NULL) {
        return;
    }
    in_display(root->left);
    printf("\n\tAuthor Name \t\t- %s", root->author);
    printf("\n\tBook Title \t\t- %s", root->title);
    printf("\n\tISBN \t\t\t- %s", root->ISBN);
    printf("\n\tPublication Date \t- %s\n", root->pubDate);
    in_display(root->right);
}
struct node* delete_node(struct node* root, char deleteAuthor[]) {
    if (root == NULL) {
        return root;
    }
    else if (strcmp(deleteAuthor, root->author) < 0) {
        root->left = delete_node(root->left, deleteAuthor);
        printf("\nBook Record Not Found\n");
    }
    else if (strcmp(deleteAuthor, root->author) > 0) {
        root->right = delete_node(root->right, deleteAuthor);
        printf("\nBook Record Not Found\n");
    }
    else {
        if (root->left == NULL && root->right == NULL) {
            free(root);
            root = NULL;
            printf("\nBook Record Successfully Deleted\n");
        }
        else if (root->left == NULL) {
            struct node* temp = root;
            root = root->right;
            free(temp);
            temp = NULL;
            printf("\nBook Record Successfully Deleted\n");
        }
        else if (root->right == NULL) {
            struct node* temp = root;
            root = root->left;
            free(temp);
            temp = NULL;
            printf("\nBook Record Successfully Deleted\n");
        }
        else {
            struct node* temp = root;
            root->left = FindMin(root);
            root->left->right = root->right;
            root = root->left;
            strcpy(temp->author, root->author);
            strcpy(temp->title, root->title);
            strcpy(temp->ISBN, root->ISBN);
            strcpy(temp->pubDate, root->pubDate);
            free(temp);
            temp = NULL;
            printf("\nBook Record Successfully Deleted\n");
        }
        return root;
    }
    return root;
}

struct node* FindMin(struct node* root) {
    while (root->left != NULL) {
        root = root->left;
    }
    return root;
}
void search(struct node* root, char searchAuthor[]){
    if (root->author < searchAuthor) {
        return search(root->right, searchAuthor);
    }
    else if (root->author > searchAuthor) {
        return search(root->left, searchAuthor);
    }
    else {
        printf("\n\t\t\t--------Searched Book Found--------\n");
        printf("\n\t\t\tAuthor Name \t\t- %s", root->author);
        printf("\n\t\t\tBook Title \t\t- %s", root->title);
        printf("\n\t\t\tISBN \t\t\t- %s", root->ISBN);
        printf("\n\t\t\tPublication Date \t- %s\n", root->pubDate);
        //return root;
    }
}

Upvotes: 0

Views: 54

Answers (1)

trincot
trincot

Reputation: 351403

There is much to be improved in your code, but I will just focus on the search function here:

  • It should handle the case when root is NULL. By not doing this, you will eventually access root->left or root-right when root is NULL which produces an exception.

  • Character arrays are not compared like you do it now. Your code is currently comparing pointer values. Use strcmp instead.

  • Using return when the functions type is void is contradictory. I would suggest changing the function's return type to struct * node, and let the function return the found node, if any, or NULL otherwise.

So:

struct node * search(struct node* root, char searchAuthor[]){
    if (root == NULL) {
        printf("\n Book not found");
        return NULL;
    }
    int diff = strcmp(root->author, searchAuthor);
    if (diff < 0) {
        return search(root->right, searchAuthor);
    }
    else if (diff > 0) {
        return search(root->left, searchAuthor);
    }
    else {
        printf("\n\t\t\t--------Searched Book Found--------\n");
        printf("\n\t\t\tAuthor Name \t\t- %s", root->author);
        printf("\n\t\t\tBook Title \t\t- %s", root->title);
        printf("\n\t\t\tISBN \t\t\t- %s", root->ISBN);
        printf("\n\t\t\tPublication Date \t- %s\n", root->pubDate);
        return root;
    }
}

A final comment on this function: it would be better practice to remove all printing from this function (and other functions), and only do the printing in the main code. This makes your functions independent of I/O matters, which is a good thing.

Upvotes: 1

Related Questions