链表首元素增删异常:插入无效、删除触发无限循环排查
C语言链表首元素插入与删除问题排查
问题现象
正在学习DSA,用C语言实现链表首元素的插入与删除操作时遇到两个问题:
- 插入首元素时无法成功添加
- 删除首元素时触发无限循环,无法定位问题
尝试过以下代码保存新指针位置,但未生效:
new->next = head; head = new;
完整代码
#include <stdio.h> #include <stdlib.h> struct Linked_List { int number; struct Linked_List *next; }; typedef struct Linked_List node; void create(node *p); int count(node *p); void print(node *p); node *insert(node *head); node *find(node *p, int key); node *delete(node *head); int main() { node *head; head = (node *)malloc(sizeof(node)); create(head); printf("\n"); print(head); printf("\n\nThe total number of elements in the linked list are :- %d",count(head)); printf("\n"); insert(head); printf("\n"); print(head); printf("\n"); delete(head); printf("\n"); print(head); } void create(node *p) { printf("\nInput number (Input -999 to end) :- "); scanf("%d", &p->number); if (p->number == -999) { p->next = NULL; } else { p->next = (node *)malloc(sizeof(node)); create(p->next); } } int count(node *p) { if (p->next == NULL) { return 0; } else { return 1 + count(p->next); } } void print(node *p) { if (p->next != NULL) { printf("%d --> ", p->number); if (p->next->next == NULL) { printf("%d", p->next->number); } print(p->next); } } node *insert(node *head) { node *new; node *preceding; int x, key; printf("\nEnter the new value to be added :- "); scanf("%d", &x); printf("\nValue of key item (-999 if last) {-> new -> key}:- "); scanf("%d", &key); if (head->number == key) { new = (node *)malloc(sizeof(node)); new->number = x; new->next = head; head = new; } else { preceding = find(head, key); if (preceding == NULL) { printf("\nKey not found!!\n"); } else { new = (node *)malloc(sizeof(node)); new->number = x; new->next = preceding->next; preceding->next = new; } } return head; } node *delete(node *head) { int key; node *preceding; node *p; printf("\nEnter the item to be deleted :- "); scanf("%d",&key); if (head->number == key) { p = head->next; free(head); head = p; } else { preceding = find(head, key); if (preceding == NULL) { printf("\nKey not found!!\n"); } else { p = preceding->next->next; free(preceding->next); preceding->next = p; } } return head; } node *find(node *p, int key) { if (p->next->number == key) { return p; } else { if (p->next->next == NULL) { return NULL; } else { find(p->next, key); } } }
问题根源与解决方法
1. 主函数未接收insert/delete的返回值
C语言参数是值传递,你在insert/delete函数里修改的head只是函数内部的副本,主函数里的原head指针完全没变化。这直接导致:
- 插入新首元素后,主函数还是指向旧节点,看不到新元素
- 删除首元素后,主函数的
head指向已被free的内存,访问时触发未定义行为(比如无限循环)
修正方法:在主函数中接收返回的新head指针:
// 替换原调用代码 head = insert(head); head = delete(head);
2. find函数递归返回值丢失
find函数递归调用时没有返回结果,导致当key不在前两个节点时,函数会返回随机垃圾值,可能引发后续操作错误。
修正方法:递归调用时返回结果:
node *find(node *p, int key) { if (p->next->number == key) { return p; } else { if (p->next->next == NULL) { return NULL; } else { // 新增return,把递归结果返回上层 return find(p->next, key); } } }
3. 其他潜在优化点
create函数逻辑:如果第一个输入是-999,会创建一个无效的终止节点,建议改为初始head = NULL,在create中处理空链表的情况,避免无效节点。print函数逻辑冗余,可以简化为更清晰的递归写法:
void print(node *p) { if (p == NULL || p->number == -999) return; printf("%d", p->number); if (p->next != NULL && p->next->number != -999) { printf(" --> "); } print(p->next); }
内容的提问来源于stack exchange,提问作者X_Abhishek_X
相关产品推荐
相关产品推荐

