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

人气:143 发布:2023-01-03 标签: struct linked-list c pointers singly-linked-list

问题描述

此程序应删除单链表中的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 	 : %d
", 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
");
    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("

before
");
    printlist(head);
    deletenode(head,N);
    printf("

after
");
    printlist(head);

}

我使用current作为临时指针,因为在第二个节点上的Head移动之后,我需要一个指向旧Head的指针并使用Free。

推荐答案

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 *的指针,我们不需要不同地处理head(astruct node *)和prev_node->next(astruct 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;
}

16