如何删除c中链表中的头部?

how to delete head in a linked list in c?

这个程序应该删除单向链表中的N节点。如果我输入 N = 1 或 N = 2 没关系,程序就可以运行。但是当 N = 0 时,输出会打印出具有随机值的无限节点(在删除节点 0 之后)。我认为程序看不到新的头部。感谢您的帮助!

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

#define N 0

struct node {
    int data;
    struct node *next;
};


void printlist(struct node *head){
    struct node *current=head;
    int i=0;
    while (current!=NULL){
        printf("node number %d \t : %d\n", i, current->data);
        current=current->next;
        i++;
    }
}


int deletenode(struct node *head,int n){
    struct node *current=head;
    struct node *previous=head;

    int i=0;

    while(current!= NULL){

        if (n==i && i!=0){
            previous->next=current->next;
            free(current);
            return 1;
        }
        else if (n==i && i==0){
            head=head->next;
            free(current);
            return 1;
        }
        i++;
        previous=current;
        current=current->next;
        return 0;
    }

    printf("error\n");
    exit(EXIT_FAILURE);
}


void main(){

    struct node *n1=malloc(sizeof(struct node));
    struct node *n2=malloc(sizeof(struct node));
    struct node *n3=malloc(sizeof(struct node));

    struct node *head=n1;
    n1->data=5;
    n1->next=n2;
    n2->data=10;
    n2->next=n3;
    n3->data=15;
    n3->next=NULL;

    printf("\n\nbefore\n");
    printlist(head);
    deletenode(head,N);
    printf("\n\nafter\n");
    printlist(head);

}

我正在使用 current 作为临时指针,因为在第二个节点上的磁头移位后我需要一个指向旧磁头的指针并免费使用。

C 始终按值传递,因此更改参数对调用者没有影响。

void foo(int i) {
   i = 1234;  // No effect on caller.
}

void foo(int *p) {
   p = NULL;  // No effect on caller.
}

如果你想修改一个变量(比如调用者的head),你需要传递一个指向它的指针。 (您仍然可以更改指针引用的内容。)

int deletenode(struct node **head, int n) {
   ...
}

deletenode(&head, N);

现在,您可以简单地将代码中 head 的每个实例替换为 (*head) 以说明新的调用约定,但这会浪费一个简化的机会。通过指向 struct node * 的指针,我们不需要以不同方式处理 headstruct node *)和 prev_node->nextstruct node *)。

int delete_node_n(struct node **ptr, unsigned n) {
    // Make `ptr` point to the pointer we want to modify.
    // This will either be the `head` variable
    // or the `next` field of some node.
    while (1) {
       if (!*ptr)
          return 0;

       if (!n)
          break;

       ptr = &( (*ptr)->next );
       --n;
    }

    struct node *to_free = *ptr;
    *ptr = (*ptr)->next;
    free(to_free);
    return 1;
}