题目链接:
力扣https://leetcode-cn.com/problems/remove-linked-list-elements/description/
解题思路:
1. 要先设出俩个指针变量 cur 与 prev ,使得这俩个指针在移动的时候始终保证 prev 在 cur 指针的前面
2. prev 指针的存在就是为了可以将要删除掉元素的其左右俩个元素链接起来
3. 如果一个单链表中全是要删除的数字,如图所示:
其本质上是 “头删” 问题。
错误原因:
prev 在没有移动前是一个空指针,
而当单链表中的第一个数字便是要删除的数字时,
上图代码中的 prev->next 就是对空指针进行操作,所以会导致程序出bug。
需要改进代码,改进后如下:
改进后的思路:
因为按照上述逻辑,如果遇到 “头删” 的情况,则 prev 指针为空指针,cur 指针为头指针
为了程序不出 bug ,所以要单独处理这种情况。
即直接对头结点进行释放,这样会产生新的头结点,
所以要先把新的头指针展现出来,
然后对最初的头结点进行释放,
最后把 cur 的位置改为新的头结点所在的位置处
参考代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val)
{
struct ListNode *prev = NULL;
struct ListNode *cur = head;
while (cur != NULL) //可以保证将链表中不止一个要删除的数全部删除
{
if (cur->val == val)
{
if (prev == NULL)//或者是 cur == head
{
head = cur->next;
free(cur);
cur = head;
}
else
{
prev->next = cur->next;
// free(prev->next);
free(cur);
cur = prev->next; //删除元素后cur指向之前被删除元素的下一个元素的位置
}
}
else
{
prev = cur;
cur = cur->next;//前后顺序不能颠倒
}
}
return head;//如果存在“头删”操作,则会对头指针进行更新
}