You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

链表首元素增删异常:插入无效、删除触发无限循环排查

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 20:05:19