我的功能之一是意外地从列表中删除元素

时间:2019-06-02 21:59:57

标签: c linked-list nested-lists

我正在尝试创建一个“图书馆”,其中包含按字母顺序排序的目录,并且每个目录都有按字母顺序排列的书籍。作为deletebook函数的一部分(由于不存在而未包括在内),我编写了查找该书目录的函数。该功能有效,但它会删除过程中的书籍(我认为),这不好。如何更改它以免删除它们?

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

struct book
{
    char *title;
    int number;
    char *country;
    struct book* new;
};

struct catalog
{
    char *name;
    struct catalog* next;
    struct book* firstbook;
};

void printList(struct catalog *head)
{
    struct catalog *temp = head;

    while(temp != NULL)
    {
        struct book* book = temp->firstbook;
        if(book == NULL)
        {
            printf("%s\n", temp->name);
        }
        while(book != NULL)
        {
            printf("%s  ", temp->name);
            printf("%s  ", book->title);
            printf("%d  ", book->number);
            printf("%s\n", book->country);
            book = book->new;
        }
        temp = temp->next;
    }
}
struct catalog *newcatalog(char *new_name)
{
    struct catalog* new_node = (struct catalog*) malloc(sizeof(struct catalog));
    new_node->name = malloc(strlen(new_name)+1);
    strcpy(new_node->name, new_name);
    new_node->next =  NULL;
    new_node->firstbook = NULL;
    return new_node;
}

struct book *newbook(char *booktitle, int number, char *country)
{
    struct book* newbook = (struct book*) malloc(sizeof(struct book));
    newbook->title = malloc(strlen(booktitle)+1);
    newbook->country = malloc(strlen(country)+1);
    strcpy(newbook->title, booktitle);
    strcpy(newbook->country, country);
    newbook->number = number;
    newbook->new = NULL;
    return newbook;
}
struct catalog *findcatalog(struct catalog** head, char *catalogname)
{
    struct catalog* current;
    current = *head;
    while(current != NULL)
    {
        if(!strcmp(current->name,catalogname))
        {
            return current;
        }
        current = current->next;
    }
    return NULL;
}


struct catalog *findbookcatalog(struct catalog** head, int number) //function that deletes a book when used
{
    struct catalog* current;
    current = *head;
    while(current != NULL)
    {
        while(current->firstbook != NULL)
        {
            if(current->firstbook->number == number)
            {
                return current;
            }
            current->firstbook = current->firstbook->new;
        }
        current = current->next;
    }
    return NULL;
}
struct book *findbook(struct catalog** head, int number)
{
    struct catalog* current = findbookcatalog(head, number);
    struct book* booklocation;
    while(current->firstbook != NULL)
    {
        booklocation = current->firstbook;
        if(current->firstbook->number == number)
        {
            return booklocation;
        }
    current->firstbook = current->firstbook->new;
    }
    return NULL;
}

void sortedBookInsert(struct catalog** head, char *catalogname, char *booktitle, int number, char *country)
{
    struct catalog* searched;
    struct book* pom;
    struct book* ksiazka = newbook(booktitle, number, country);
    searched = findcatalog(head, catalogname);

    if(searched->firstbook == NULL || strcmp(searched->firstbook->title, ksiazka->title)>0)
    {
        ksiazka->new =searched->firstbook;
        searched->firstbook = ksiazka;
    }
    else
    { pom = searched->firstbook;
        while(pom->new!= NULL && strcmp(searched->firstbook->title, ksiazka->title)< 0)
        {
            pom = pom->new;
        }
        ksiazka->new = pom->new;
        pom->new = ksiazka;
    }
}
void sortedInsert(struct catalog** head,char *name)
{
    struct catalog* current;
    struct catalog* new_node = newcatalog(name);
    if(new_node == NULL)
    {
        return;
    }

    if (*head == NULL || strcmp((*head)->name, new_node->name) > 0)
    {
        new_node->next = *head;
        *head = new_node;
    }
    else
    {
        current = *head;
        while (current->next!=NULL && strcmp(current->next->name, new_node->name) < 0)
        {
            current = current->next;
        }
        new_node->next = current->next;
        current->next = new_node;
    }
}
int main()
{

    struct catalog* head = NULL;
    sortedInsert(&head, "Kappa");
    sortedInsert(&head, "Pxntry");
    sortedInsert(&head, "Sdafscx");
    sortedInsert(&head, "Saxzxc");
    sortedInsert(&head, "Zsdas");
    sortedInsert(&head, "Zzzzzzzz");
    sortedInsert(&head, "Country");
    sortedBookInsert(&head, "Country", "PKP", 11111, "Germany");
    sortedBookInsert(&head, "Country", "Polacy", 11112, "Italy");
    sortedBookInsert(&head, "Country", "Bus", 11234, "France");
    sortedBookInsert(&head, "Country", "Poltics", 14111, "Russia");
    printList(head);
    findbookcatalog(&head, 11112); // this will "eat" "Bus" and "PKP", so books that appear before Polacy
    printf("\n");
    printList(head);
    return 0;
}

它应该两次打印我的嵌套列表,两次相同,但是会删除搜索到的书之前的所有书。

结果:

Country  Bus  11234  France
Country  PKP  11111  Germany
Country  Polacy  11112  Italy
Country  Poltics  14111  Russia
Kappa
Pxntry
Saxzxc
Sdafscx
Zsdas
Zzzzzzzz

Country  Polacy  11112  Italy
Country  Poltics  14111  Russia
Kappa
Pxntry
Saxzxc
Sdafscx
Zsdas
Zzzzzzzz

1 个答案:

答案 0 :(得分:1)

此代码正在从列表中删除图书:

current->firstbook = current->firstbook->new;

您可能打算使用以下内容:

current_book = current->firstbook;
while (current_book) {
    if (current_book->number == number) {
        return current_book;
    }
    current_book = current_book->new;
}

我更改了此功能以解决您当前的问题:

struct catalog *findbookcatalog(struct catalog** head, int number) //function that deletes a book when used
{
    struct catalog* current;
    current = *head;
    struct book *current_book;
    while(current != NULL)
    {
        current_book = current->firstbook;
        while(current_book != NULL)
        {
            if(current_book->number == number)
            {
                return current;
            }
            current_book = current_book->new;
        }
        current = current->next;
    }
    return NULL;
}

我也更改了此功能。它有同样的问题,您还没有测试过。

struct book *findbook(struct catalog** head, int number)
{
    struct catalog* current = findbookcatalog(head, number);
    struct book* booklocation;
    if (current != NULL) {
        booklocation = current->firstbook;
        while(booklocation != NULL)
        {
            if(booklocation->number == number)
            {
                return booklocation;
            }
            booklocation = booklocation->new;
        }
    }
    return NULL;
}