力扣链接
题目描述
解题思路1
主要逻辑:
- 创建cur指针指向头结点,创建prev指针作为cur指针的前驱指针;
- cur指针从头结点开始遍历;
- 如果cur->val = val ,则让前驱指针(prev)的指针域指向当前指针(cur)的指针域,然后释放掉cur指针所指向的空间,cur指针指向前驱指针的指针域;
- 如果cur->val != val ,将cur赋值给prev,cur指向cur->next。
细节处理: 特别处理第一个结点就是要删除的结点,如果不处理,此时的前驱指针为空,进行prev->next操作的时候就会出现空指针异常。
- 如果cur->val = val并且cur = head,此时要删除的就是第一个结点;
- 让cur指针指向头结点的指针域,然后释放掉cur指针所指向的空间;
- 将cur赋值给head。
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode* cur = head;
struct ListNode* prev = NULL;
while(cur)
{
if(cur->val == val)
{
if(cur == head)
{
//头删
cur = head->next;
free(head);
head = cur;
}
else
{
//正常删
prev->next = cur->next;
free(cur);
cur = prev->next;
}
}
else
{
prev = cur;
cur = cur->next;
}
}
return head;
}
解题思路2
遍历原链表,把不是val的结点拿出来进行尾插到新节点
1.创建一个尾指针初始化为空,创建一个cur指针指向头结点;
2.遍历原链表;
3.如果cur->val = val,进行删除操作
4.如果要删除的是头结点,移动cur指针指向下一个结点;
5.释放head所指向的空间,让head指向cur;
6.如果cur->val != val,将这个节点尾插到头结点;
7.如果tail=NULL,将头结点和尾节点都指向cur所指向的结点;
8.若果tail不为空,让tail的指针域指向cur所指向的结点,tail指针向后移动;
9.当链表遍历完,要将tail->next 置空,否则容易发生野指针异常。
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode* tail = NULL;//尾节点
struct ListNode* cur = head;
while(cur)
{
if(cur->val == val)
{
//删除
if(cur == head)
{
cur = cur->next;
free(head);
head = cur;
}
else
{
struct ListNode* del = cur;
cur = cur->next;
free(del);
}
}
else
{
//不相等将该节点尾插到head后边
if(tail == NULL)
{
head = tail = cur;
}
else
{
tail->next = cur;
tail = tail->next;
}
}
cur = cur->next;
}
tail->next = NULL;
return head;
}