题目
在单链表中查找并删除第一个节点值等于目标值 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