22.删除链表结点
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。返回删除后的链表的头节点。
- 此题对比原题有改动。
- 题目保证链表中节点的值互不相同。
- 该题只会输出返回的链表和结果做对比,所以若使用 C 或 C++ 语言,你不需要 free 或 delete 被删除的节点。
数据范围: 0<=链表节点值<=10000 0<=链表长度<=10000 。
示例
输入:
2 5 1 9
5
输出:
2 1 9
说明: 给定你链表中值为5的第二个节点,那么在调用了你的函数之后,该链表应变为 2->1->9。
输入:
2 5 1 9
1
输出:
2 5 9
说明:给定你链表中值为1的第三个节点,那么在调用了你的函数之后,该链表应变为 2->5->9。
复制代码
思路
从头开始遍历链表,比较节点数据,如果相等就删除,最后返回头节点即可。
- 表头加入一个虚拟头节点,以便统一删除操作。
- if判断里面使用cur->next->val,代表当前判断的是cur所指节点的下一个节点,方便删除操作(因为cur为当前判断节点的前驱节点)。
具体实现
// 删除链表结点
#include<stdio.h>
struct LNode {
int data;
LNode* next;
LNode() :data(0), next(nullptr) {} //初始化
LNode(int x) :data(x), next(nullptr) {}
};
int main() {
int data, data1;
LNode* head = new LNode(); //定义头结点
LNode* p = head; //p保存头结点
printf("输入数据:");
while (scanf_s("%d",&data)) {
LNode* s = new LNode(data);
head->next = s;
head = head->next;
if (getchar() == '\n') break; //当换行时,就跳出循环,即输出完毕!
}
printf("输入要删除的值:");
scanf_s("%d", &data1); //输入要删除的结点值
p = p->next; //p指向head的第一个数,而不是从空头结点开始
while (p) {
if (p->data == data1) {
p = p->next;
}
else {
printf("%d ", p->data);
p = p->next;
}
}
return 0;
}
运行结果
复杂度
- 时间复杂度 O(n) --- 遍历链表,n为链表长度
- 空间复杂度 O(1) --- 链表为必要空间,无额外辅助空间。