【问题标题】:how to delete head in a linked list in c?如何在c中删除链表中的头?
【发布时间】:2020-05-12 06:56:53
【问题描述】:

这个程序应该删除单链表中的 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作为临时指针,因为在第二个节点上的磁头移位后,我需要一个指向旧磁头的指针并免费使用。

【问题讨论】:

  • deletenode 应该返回一个指向新头的指针

标签: c pointers struct linked-list singly-linked-list


【解决方案1】:

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(struct node *)和prev_node-&gt;next(struct 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;
}

【讨论】:

  • 谢谢,我会试试的。你能帮我理解为什么在这种情况下我需要一个指向指针的指针吗?
  • 因为 C 总是按值传递。更改参数对调用者没有影响。添加到答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
  • 2015-05-08
  • 1970-01-01
  • 1970-01-01
  • 2017-08-25
  • 1970-01-01
相关资源
最近更新 更多