我使用链表(没有数组)创建了一个堆栈,但我的 pop 函数不起作用

I made a stack using linked list (without array), but my pop function is not working

在我的 pop 函数中,我将 head 的地址存储在 temp 中,然后继续。当我在 temp 中遇到死胡同时,我通过将 NULL 分配给它来将其删除。但是,当我打印堆栈时,它并没有删除最后一次推送。

我试过使用 temp->next=NULL 。只有这样它才能工作,但如果 temp->next=NULL 工作。 temp=NULL 不应该也有效吗?

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

struct student
{
    char name[20];
    int id;
    double cgpa;
    struct student* next;
} *head;

void print()
{
    struct student* temp = head;
    while(temp != NULL)
    {
        printf("id %d name %s cgpa %lf\n", temp->id, temp->name, temp->cgpa);
        temp = temp->next;
    }
}

void push(struct student* temp)
{
    if(head == NULL)
    {
        head = temp;
        return;
    }
    struct student* current = head;
    while(current->next != NULL)
    {
        current = current->next;
    }
    current->next=temp;
}

void pop()
{
    struct student* temp = head;
    if(head == NULL)
    {
        printf("\n no element to pop\n");
    }
    else
    {
        while(temp->next != NULL)
        {
            temp = temp->next;
        }
        temp = NULL;
    }
}

int main()
{
    char operation;
    struct student* temp = NULL;
    head = NULL;

    while(1)
    {
        // a for ADD, r for POP, s for print
        scanf("%c", &operation);
        if(operation == 'a')
        {
            temp = (struct student*)malloc(sizeof(struct student));
            scanf("%d %s %lf", &temp->id, &temp->name, &temp->cgpa);
            temp->next = NULL;
            push(temp);
        }
        else if(operation == 'r')
        {
            pop();
        }
        else if(operation == 's')
        {
            print();
        }
    }
}

a
1 joy 2.3
a
5 boy 3.3
s
r
s

预期结果应该是:

1 joy 2.3
5 boy 3.3

1 joy 2.3

但实际结果是

1 joy 2.3
5 boy 3.3

1 joy 2.3
5 boy 3.3

该函数更改局部变量temp而不是更改列表最后一个节点之前的节点的数据成员next

可以这样看

void pop()
{
    if ( head == NULL )
    {
        printf("\n no element to pop\n");
    }
    else
    {
            struct student **temp = &head;

            while ( ( *temp )->next != NULL )
            {
                temp = &( *temp )->next;
            }

            free( *temp );
            *temp = NULL;
    }
}

现在变量temp正好指向最后一个节点之前节点的数据成员next。那就是列表本身被改变了。

不要忘记释放最后一个节点。

流行音乐不起作用是你的权利。当您找到结束元素时,您所做的就是将临时指针设置为 NULL。你需要做的是先释放temp中的元素,然后将前一个元素指向它的指针设置为NULL。

void pop()
{
    if(head==NULL){
       printf("\n no element to pop\n");
}
else
{
   struct student* temp=head;
    struct student* previous=head;
    while(temp->next!=null){
        previous=temp;
        temp=temp->next;
    }
    if(previous!=next) //if there was more than one
    {
      previous->next=NULL;
    }
    else
    {
     head=NULL;
    }

    free(temp);


}

}

代码 temp=NULL 将变量 temp 设置为空,而不是 temp 的字段 next。对于后者,它实际上并没有删除节点。