簡體   English   中英

無法刪除鏈表中的第一個節點

[英]not being able to delete the first node in a linked list

#include <stdio.h>
#include <stdlib.h>
#define N 10

typedef struct music_student *StudentPtr;
typedef struct music_student
{
    int student_ID;
    double hw_average;
    int exam_grade;
    int final_grade;
    StudentPtr next;
} Music_student;
StudentPtr creatnew(int id,double hw,int exam);
StudentPtr Del(int id,StudentPtr list);
StudentPtr insert(int id,double hw,int exam,StudentPtr list);
void Proportion(float prop,StudentPtr list);
int main()
{
    int req,id,exam;
    double avg;
    float prop;
    StudentPtr list=NULL;
    printf("Course Management Menu\nPlease choose among the following:\n");
    printf("***\n");
    printf("0: Quit.\n1: Insert student at first place on the list.\n2: Delete by ID.\n3: Find lucky student.\n4: Change homework exam ratio.\n5: Print List.\n");
    while (N<15)
    {
        if(scanf("%d",&req)!=1)
        {
            printf("Input Error!");
            return 1;
        }
        while(req>6||req<0)
        {
            printf("Invalid Selection\n");
            if(scanf("%d",&req)!=1)
            {
                printf("Input Error!");
                return 1;
            }
        }
        switch (req)
        {
        case 1:
            printf("insert student ID\n");
            scanf("%d",&id);
            while(id<10000||id>99999)
            {
                printf("Invalid student id try_again: value between 10,000 and 99,999\n");
                scanf("%d",&id);
            }
            printf("insert hw grade\n");
            scanf("%lf",&avg);
            while(avg>100||avg<0)
            {
                printf("Invalid hw grade: value between 0 and 100\n");
                scanf("%lf",&avg);
            }
            printf("insert exam grade\n");
            scanf("%d",&exam);
            while(exam>100||exam<0)
            {
                printf("Invalid exam grade: value between 0 and 100\n");
                scanf("%d",&exam);
            }
            list=insert(id,avg,exam,list);
            break;
        case 2:
            printf("Enter student to expunge from records:\n");
            scanf("%d",&id);
            Del(id,list);
            break;
        case 3:
            Lucky(list);
            break;
case 5:
            lilPrint(list);
            break;
        case 0:
            printf ("bye bye!");
            return 0;
        }
    }
}
void lilPrint(StudentPtr list)
{
    StudentPtr temp = list;
    if(list==NULL)
        return;
    while (temp != NULL)
    {
        printf("Student Id: %d\nFinal Grade: %d\n",temp->student_ID,temp->final_grade);
        temp = temp->next;
    }
    return;
}
StudentPtr Del(int id, StudentPtr list)
{
    StudentPtr curr = list, prev = NULL;
    if(curr->student_ID==id)
    {
        list=list->next;
        free(curr);
        curr=list;
    }
    while (curr != NULL)
    {
        if (curr->student_ID == id)
            {
            if (prev == NULL)
                {
                list = curr->next;
                }
            else
            {
                prev->next = curr->next;
            }
            free(curr);
            return list;
            }
        prev = curr;
        curr = curr->next;
    }
    return list;
}
StudentPtr insert(int id,double hw,int exam,StudentPtr list)
{
    StudentPtr cell=creatnew(id,hw,exam);
    if(cell==NULL)
    {
        free(list);
        exit(1);
    }
    cell->next=list;
    list=cell;
    return list;
}
StudentPtr creatnew(int id,double hw,int exam)
{
    StudentPtr cell=(StudentPtr)malloc(sizeof(Music_student));
    if(cell == NULL)
    {
        printf("Allocation failed!");
        return NULL;
    }
    cell->exam_grade=exam;
    cell->student_ID=id;
    cell->hw_average=hw;
    cell->final_grade=(my_round(0.7*cell->exam_grade)+my_round(cell->hw_average*0.3));
    cell->next=NULL;
    return cell;
}

我試圖在其中輸入 4 或 5 個節點,並使用 lilprint 打印有關鏈表的一些信息。 當我輸入一些節點然后刪除第一個節點時(只刪除第一個節點會出現這個問題)程序不會完全刪除它所以它只會刪除該節點中的 student_id 並返回 rest。所以當我打印它時它打印正常但是student_id 是垃圾值。

這個定義和使用N與幻數10以及另一個幻數15

#define N 10
//...

while (N<15)
//... 

使您的代碼不清楚。

還有這個指針的 typedef 聲明

typedef struct music_student *StudentPtr;

是個壞主意。 例如,如果您將編寫const StudentPtr ,那么它將等同於struct music_student * const而不是const struct music_student *並且最后的類型規范應該在 function lilPrint中使用,因為在 function 中列表沒有改變。

void lilPrint( const struct music_student *list);

順便說一下,您忘記將 function 聲明放在 main 之前。

在function中insert這條語句

free(list);

沒有意義,因為它沒有釋放所有分配的 memory。

function Del可以在列表為空時調用 undefined 由於使用 null 指針訪問 memory 作為此語句中的示例

if(curr->student_ID==id)

此外,列表似乎應該存儲具有唯一student_ID的節點,但 function Del的設計方式是,由於第一個 if 語句之后的 while 循環,它最多刪除兩個具有相同student_ID的節點

if(curr->student_ID==id)
{
    list=list->next;
    free(curr);
    curr=list;
}
while (curr != NULL)
{
    if (curr->student_ID == id)
        {
        if (prev == NULL)
            {
            list = curr->next;
            }
        else
        {
            prev->next = curr->next;
        }
        free(curr);
        return list;
        }
        //...

也就是說 function 應該刪除具有相同student_ID的所有節點或只刪除一個具有給定id的節點。

主要是你忘了將返回的指針分配給指針list

Del(id,list);

相反,你需要寫

list = Del(id,list);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM