题目

在单链表中查找并删除第一个节点值等于目标值 x 的节点,输出删除后的新链表内容。

输入格式:第一行输入节点数量 n;第二行输入 n 个整数建立链表;第三行输入待删除的值 x。

输出格式:输出删除目标节点后的完整链表,每个数字后跟空格,末尾换行。

数据范围与约定:1 ≤ n ≤ 100。

思路与算法

1. 头节点删除特判
若被删节点正好是头节点 head->val == x,直接将 head 更新为 head->next,并 free 原头节点。

2. 中间/尾部节点删除
维护前驱指针 prev 和当前指针 cur。命中后执行 prev->next = cur->next; free(cur); 完成跨节点断开与空间回收。

完整程序

#include <stdio.h>
#include <stdlib.h>

struct Node {
    int v;
    struct Node *next;
};

int main(void)
{
    int n, x, v;
    // 哑节点(虚拟头节点 dummy)技巧:统一头节点与中间节点的删除逻辑,避免特判
    struct Node dummy = {0, NULL}, *tail = &dummy;
    scanf("%d", &n);

    // 尾插法建表
    for (int i = 0; i < n; i++) {
        scanf("%d", &v);
        struct Node *p = malloc(sizeof *p);
        p->v = v;
        p->next = NULL;
        tail->next = p;
        tail = p;
    }

    scanf("%d", &x);
    struct Node *p = &dummy;
    // 查找目标节点的前驱节点
    while (p->next && p->next->v != x) {
        p = p->next;
    }

    // 若找到目标节点,修改指针跳过它,并释放其占用的堆内存
    if (p->next) {
        struct Node *del = p->next;
        p->next = del->next;
        free(del);
    }

    for (p = dummy.next; p; p = p->next) {
        printf("%d ", p->v);
    }
    putchar('\n');
    return 0;
}

运行示例

输入:

4
1 2 3 2
2

输出:

1 3 2