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

如何合并C语言链表字符删除函数以处理首节点及非首节点场景

合并链表字符删除函数的实现

我用C语言实现了一个存储字符的链表来表示字符串,写了removeChars函数删除从位置pos开始的lnth个字符:

listNode *removeChars(listNode *wordList, int pos, int lnth) {
    listNode *curr = wordList;
    listNode *prev = NULL;

    for (int i = 0; i < pos-1; i++) {
        prev = curr;
        curr = curr->next;
    }
    for (int i = 0; i < lnth; i++)
       curr = curr->next;
    prev->next = curr;
    return wordList;
}

这个函数在pos > 1时能正常工作,但pos == 1时会失效——因为此时prev还是NULL,访问prev->next会触发空指针错误。所以我又写了单独处理头部删除的removeFirstChar函数:

void removeFirstChar(listNode **wordList, int lnth) {
    listNode *curr = *wordList;
    for (int i = 0; i < lnth; i++)
        curr = curr->next;
    *wordList = curr;
}

现在需要把这两个函数合并成一个能同时处理pos = 1和pos > 1的函数。


合并后的实现方案

这里提供两种实用的合并方式,都能统一处理两种场景:

方案1:通过指针的指针修改头节点(无返回值)

void removeChars(listNode **wordList, int pos, int lnth) {
    // 先过滤非法输入
    if (*wordList == NULL || lnth <= 0 || pos < 1) {
        return;
    }

    listNode *curr = *wordList;
    // 定位到要删除段的前一个节点(pos>1时)
    if (pos > 1) {
        for (int i = 0; i < pos - 2; i++) {
            if (curr == NULL) break; // 防止pos超出链表长度
            curr = curr->next;
        }
    }

    // 找到删除完成后要连接的目标节点
    listNode *target = (pos == 1) ? *wordList : curr->next;
    for (int i = 0; i < lnth; i++) {
        if (target == NULL) break; // 防止lnth超出剩余节点数
        target = target->next;
    }

    // 执行删除
    if (pos == 1) {
        *wordList = target;
    } else {
        if (curr != NULL) {
            curr->next = target;
        }
    }
}

方案2:返回更新后的头节点

listNode *removeChars(listNode *wordList, int pos, int lnth) {
    // 非法输入直接返回原链表
    if (wordList == NULL || lnth <= 0 || pos < 1) {
        return wordList;
    }

    listNode *curr = wordList;
    listNode *prev = NULL;

    // 移动到要删除起始位置的前一个节点
    for (int i = 0; i < pos - 1; i++) {
        if (curr == NULL) break;
        prev = curr;
        curr = curr->next;
    }

    // 找到删除后的目标节点
    listNode *target = curr;
    for (int i = 0; i < lnth; i++) {
        if (target == NULL) break;
        target = target->next;
    }

    // 分情况处理
    if (prev == NULL) {
        // pos=1,直接返回新的头节点
        return target;
    } else {
        // pos>1,连接前节点和目标节点
        prev->next = target;
        return wordList;
    }
}

关键逻辑说明

  • 非法输入防护:提前过滤空链表、非正的删除长度、小于1的位置,避免后续空指针访问。
  • 统一节点定位:不管pos是1还是更大,先找到要删除段的起始点,再找到删除后要连接的目标节点。
  • 分支处理核心:
    • 当pos=1时,直接修改头指针(方案1通过指针的指针,方案2返回新头)。
    • 当pos>1时,找到起始点的前一个节点prev,将prev->next指向目标节点完成删除。
  • 边界处理:循环中加入curr == NULL的判断,防止pos或lnth超过链表实际长度导致崩溃。

内容的提问来源于stack exchange,提问作者Thadeu Freitas Filho

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 05:36:13