一:题目
二:思路讲解
方法一:
1:创建两个指针prev和cur,初识位置cur为head,prev为NULL,然后两个指针往后移动开始去寻找与val值吻合的节点,最后找到节点的时候,cur指向该节点,prev指向该节点的前一个节点,现在我们的目的是要删除这个cur指向的节点,让cur去指向该节点的下一个节点!
2:所以我们先将prev的next修改为该节点的下一个节点,将该节点的前后两点链接起来(prev->next = cur ->next)然后再让cur指向该节点的后一个节点(cur=prev->next )。
第一步:初始状态:
第二步:找到val值吻合的时候:
第三步: 先将prev的next修改为该节点的下一个节点,将该节点的前后两点链接起来(prev->next = cur ->next)
第四步: 然后再让cur指向该节点的后一个节点(cur=prev->next )。
这样就成功的删除了一个与val值吻合节点。
如果你疑问为什么不直接cur=cur->next,也就是直接让cur指向了该节点的下一个节点,那是因为我们需要释放掉该节点。而该节点是cur指向的,我们free(cur)的这一步,是放在第三步和第四步之间,free(cur)不会产生任何影响,如果直接cur=cur->next,那不管是在这一步之前还是之后free(cur),都会对cur产生影响,从而导致答案错误。
特殊情况:第一个或者前几个一直val值都吻合
第一步:初始状态:
这种情况,我们对prev的操作,会变成对空指针的解引用,这是错误的!
解决方法:寻找一个新的头,也就是让上面的链表变成下面:
这样又可以按照之前的方法做下去了。
代码展示:
由图可知: 判断特殊情况的if有两种写法,皆可。
方法二:
遍历原链表,把不是val的节点尾插到新链表。
1:首先需要一个cur初始为head,一个newhead(NULL),一个tail(NULL)来保存节点去进行尾插,这两个一开始都是NULL,因为可能链表是一个空链表,这样直接返回newhead就好
第一步:发现val值吻合的节点