第一种思路
循环遍历整个链表
定义两个指针:prev,cur
如果cur是要删除的节点,prev->cur->next,然后free(cur)
但是注意每次都要新定义一个节点del,用来free,不影响原来的cur节点往下循环
更新cur和prev
但是需要注意如果删除的是头节点,就要特殊处理,画图带上指针,情况分析,一目了然。
思路一代码:
cs
struct ListNode* removeElements(struct ListNode* head, int val) {
struct ListNode *cur =head;
struct ListNode *prev = NULL;
while(cur)
{
struct ListNode *del = cur;
if(del->val == val)
{
cur = cur->next;
free(del);
//如果是头节点,需要更新头节点
if(prev == NULL)
{
head = cur;
}
else
{
prev->next = cur;
}
}
else
{
prev = cur;
cur = cur->next;
}
}
return head;
}
第二种思路:
创建新链表,不等于val的节点尾插到新链表,返回新链表
这种方式需要画出详细的过程图,否认坑很多
需要注意的点:
1、链表为空
2、最后一个节点是要不要的节点,涉及到新链表的最后一个节点的下一个节点是野指针问题,这个可以到VS上进行调试
第二种思路代码:
cs
struct ListNode* removeElements(struct ListNode* head, int val) {
struct ListNode *cur = head;
struct ListNode *newNode = NULL, *tail =NULL;
while(cur)
{
//不等于值,尾插
if(cur->val != val)
{
//头节点为空
if(tail == NULL)
{
tail = newNode = cur;
}
else
{
tail->next = cur;
tail = tail->next;
}
cur = cur->next;
}
else
{
struct ListNode *del = cur;
cur = cur->next;
free(del);
}
//如果删除的是最后一个节点
//会出现野指针的问题
//对空链表进行检查
if(tail)
tail->next = NULL;
}
return newNode;
}