c - 删除函数无法删除链表中除第一个节点之外的节点

标签 c linked-list

我一直在研究图书馆管理系统。我快完成了。以下程序是使用代码块编辑器在 C 语言上编写的。

我有两个问题 1. 如果我尝试删除第一个节点以外的节点,程序将停止响应 omit() 函数 else 语句似乎有问题。 2. bsort() 函数是链表中冒泡排序的正确实现吗?它工作完美。只是想知道是否可以将其称为冒泡排序。

// Imports
//---------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//---------------------------------------------
// Definitions
//---------------------------------------------
#define MAX_STRING_LENGTH 50
//---------------------------------------------
// Type definitions to make the code more readable
//---------------------------------------------
typedef struct node {
    char *name;
    char *author;
    struct node * next;
} Node;
//---------------------------------------------
// Global Variable
//---------------------------------------------
Node* head = NULL;
//---------------------------------------------
// Function protoypes
//---------------------------------------------
void insert(char *q, char *r);
void print_the_list();
void bsort();
void search();
void omit();
//---------------------------------------------
// Main Function :
// Ask the user to insert some books then
// print the list of books
// normally or sorted by book name
//---------------------------------------------
int main() {
    head = NULL; //Initially head is null
    char *book_name=NULL, *book_author=NULL;
    int n=NULL,i=NULL; // Number of book that the user want to enter
    printf("How many books you want to enter?: \n");
    scanf("%d", &n);
    for (i = 1; i <= n; i++){ // Loop iterate the number of times we have books 
    in quantity.
        // To clear buffer memory
        fflush(stdin);
        printf("Enter a Book name: ");
        fflush(stdin); // To clear buffer memory
        book_name = (char*) malloc(MAX_STRING_LENGTH*sizeof(char));
        gets(book_name); // Same as scanf
        printf("Author: ");
        book_author = (char*) malloc(MAX_STRING_LENGTH*sizeof(char));
        gets(book_author);
        // add it to the list
        insert(book_name, book_author);
        }
    print_the_list();
    char d=NULL;
    printf("Do you want to sort the data in ascending order?(y/n): \n\t");
    scanf("%c", &d);
    if (d == 'y') {
        printf("Sorting the list!");
        bsort();
    } else
        printf("alright!");

    print_the_list();
    omit();
    printf("Printing the modified list");
    print_the_list();
    search();
    return 0;
}
//---------------------------------------------
// insert(name of the book, author of the book):
// O(n_of_element_in_the_list)
// append the new book the global list
//---------------------------------------------
void insert(char* name, char* author){ //Adding items at the end of linked list
    // create and initialize the new node
    Node* new_node = (Node* ) malloc(sizeof(Node));
    new_node->author = author;
    new_node->name   = name;
    new_node->next   = NULL; // Since we are adding a node to the end, we are linking it to NULL.

    // if the list is empty then add the node as the head of the list
    if (head == NULL) {
        head = new_node;
    }
    else {
        Node * temp = head;
        // Traverse the list till the end
        while (temp->next != NULL)
            temp = temp->next;
        // add the new node as the successor of the last node
        temp->next = new_node;
    }
}
//---------------------------------------------
// print_the_list():
// O(n_of_element_in_the_list)
// print the whole content of the global list
//---------------------------------------------
void print_the_list() //Traversing
{
    printf("\n");
    printf("The Library data is as follows: \n");
    Node* temp=head;
    printf("\n");
    while(temp!=NULL)
    {
        printf("%25s",temp->name);
        printf("%25s",temp->author);
        temp=temp->next;
        printf("\n");
    }
}

//---------------------------------------------
// sort():
// O(n_of_element_in_the_list^2)
// sort the whole list by name in Ascending Order
//---------------------------------------------
void bsort(){ //Bubble Sort Algorithm to arrange Library data in Ascending Order

    // If he list is empty then is already sorted
    if(head == NULL)
        return;

    // Temp pointers to swap two nodes.
    char *swap_ptr_name, *swap_ptr_author;
    // Variable that keep track if at least one swap was made in the for.
    int swapped;
    Node* current_node=NULL;
    Node* next_node;
    do{
        // Reset the flag
        swapped = 0;
        // for each node in the list except the last one
        for (current_node = head; current_node->next != NULL;  current_node = current_node->next) {
            // Set the next node
            next_node = current_node->next;
            // if the current_node is bigger than the next_node swap them
            if (strcmp(current_node->name,next_node->name) > 0) {
                // Save the name and author of the current_minimum
                swap_ptr_name   = next_node->name;
                swap_ptr_author = next_node->author;

                // Place the current node as the minimum
                next_node->name   = current_node->name;
                next_node->author = current_node->author;

                // Place the old minimum in the place of the current_node
                current_node->name   = swap_ptr_name;
                current_node->author = swap_ptr_author;

                // We swapped two nodes so the flag is setted
                swapped = 1;
            }
        }
    }while(swapped == 1);
}

void search()
{
    char *keyword=NULL;
    Node* current=head;
    printf("Enter a book name or author name to search: ");
    fflush(stdin);
    keyword=(char*) malloc(MAX_STRING_LENGTH*sizeof(char));
    gets(keyword);
    for (current=head;current!=NULL;current=current->next)
    {
        if ((strcmp(current->name,keyword)==0) || (strcmp(current->author,keyword)==0)) {//||(strcmp(current->author,keyword))==0) {
            puts(current->name);
            puts(current->author);
        }
    }
}
void omit()
{
    char *keyword;
    char d;
    Node* current=head;
    Node* temp;
    printf("Enter a book name or author name to delete: ");
    fflush(stdin);
    keyword=(char*) malloc(MAX_STRING_LENGTH*sizeof(char));
    gets(keyword);
    printf("\nTrying to delete\n");
    for (current=head;current!=NULL;current=current->next)
    {
        if ((strcmp(current->name,keyword)==0) || (strcmp(current->author,keyword)==0)) {
            puts(current->name);
            puts(current->author);
            printf("Are you sure you want to delete[y/n]: ");
            fflush(stdin);
            scanf("%c",&d);
            if (d=='y') {
            printf("\nTrying to delete\n");
            if (current==head)
                {
                    head=current->next;
                    free(current);
                }
            else
                {
                    temp->next=current;
                    temp->next=current->next;
                    free(current);
                }
            }
        }
    }
}

Screenshot of malfunctioning output

最佳答案

当您要删除时,您似乎没有将前一个 block 指向新的下一个 block 。另外,else 语句中的第一行是毫无意义的,因为无论如何,下一行都会重新分配 temp->next 。您需要更改的是跟踪前一个 block ,以便当您找到要删除的 block 时,可以将前一个 block 的 next 指向当前 block 的 next

if ((strcmp(current->name,keyword)==0) || (strcmp(current->author,keyword)==0)) {
        puts(current->name);
        puts(current->author);
        printf("Are you sure you want to delete[y/n]: ");
        fflush(stdin);
        scanf("%c",&d);
        if (d=='y') 
        {
            printf("\nTrying to delete\n");
            if (current==head)
            {
                head=current->next;
                free(current);
            }
            else
            {
                if(temp == head)
                {
                    head->next = current->next;
                }
                temp->next=current->next;
                free(current);
            }
        }
        temp = current;
    }

我对代码所做的唯一更改是将 temp 设置为 current,以便循环的下一次迭代可以引用循环中的前一个 block ,并删除else 语句的第一行。

看来您的算法是有效的冒泡排序,因为您正在循环数组并交换相邻元素。

关于c - 删除函数无法删除链表中除第一个节点之外的节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51768251/

相关文章:

c - 8 位微 Controller 的 64 位整数实现

c - C语言中向链表栈添加节点

c - 将二进制搜索展平为有序的单链表 [C]

mysql - C程序向MYSQL数据库添加数据-没有添加结果

c - 从哈希表 C 中获取链表

python - python3中两个排序链表的交集?

c - fork after malloc in parent...子进程需要释放它吗?

c - 创建链表时不需要创建实际节点吗?

c - reverseList 函数不在队列中工作

java - 链接列表示例中的 "this"指的是什么?