力扣经典题目之->移除链表元素,看这篇就够了!!

一:题目

二:思路讲解 

方法一:(双指针法

我们采用的是双指针法,cur和prev,cur初识化为head,prev初始化为NULL。

两指针一前一后遍历整个链表,当cur遇到与val值节点的时候,我们就将其删除(此节点的前后节点相连接)

情况分为几种:

a:普通情况,val值节点不在第一个节点

第一步:初始状态:

第二步:找到与val值吻合的节点时候:

第三步: cur向后移动(curcur->next)

第四步: 然后再让prev指向cur(prev->next=cur)

这样就成功的删除了一个与val值吻合节点(本质是将val值节点的前后节点相连接)。

b:特殊情况,头删(val值节点处于第一个节点)

第一步:初始状态:

这种情况不能在进行遍历了,应该

解决方法:寻找一个新的头,也就是让上面的链表变成下面:

这样就变成了普通情况又可以按照之前的方法做下去了。

代码展示:

如果你想要有free的书写,可以这样: 

由图可知: 判断特殊情况的if有两种写法,皆可。

方法二:

遍历原链表,把不是val的节点尾插到新链表。

1:首先需要三个指针

a:cur初始为head,cur用来遍历链表

b:newhead(NULL),此为最后返回的新的头指针

c:tail(NULL)

链表是一个空链表,直接返回newhead即可。

2:发现与val值吻合的节点,先用一个指针del去保存这个节点,然后直接让cur指向该节点的下一个节点,然后free掉该节点,(free(del))。

3:发现与val值 不 吻合的节点,就进行尾插,尾插有两种情况,一种是第一次尾插,一种是不是第一次尾插。

第一次尾插:tail为null,要将cur赋值给newhead和tail,赋值给newhead就让其指向了第一个尾插的节点,这样newhead就是新链表的头指针了,赋值给tail是因为,tail要指向新链表的尾节点,tail会与cur进行新的尾节点的插入等工作。

不是第一次尾插:即tail不为null,先尾插,让tail指向的节点去链接到新的尾插节点(tail->next=cur),再移动tail让tail去指向新的尾插节点(tail=tail->next)。

第一步:发现val值吻合的节点,先用一个指针del去保存这个节点,然后直接让cur指向该节点的下一个节点,然后free掉该节点,(free(del))。

第二步:发现与val值 不 吻合的节点的第一次尾插

tail为null,要将cur赋值给newhead和tail

第三步:不是第一次的尾插

即tail不为null,先尾插,让tail指向的节点去链接到新的尾插节点(tail->next=cur)

再移动tail,再让tail去指向新的尾插节点(tail=tail->next)。 

代码展示: 

注意:

尾插的最后一个节点的next没有置空,所以我们在最后将tail->next=NULL,但是在这之前,我们得先判断tail是否为空,因为可能这个链表是个空链表或者全为val,这样才能避免对tail(NULL)的解引用。这一步不能在尾插的else里面进行,因为tail和cur指向的同一个节点,你把tail的next置空,cur的next也置空了,cur无法往下进行遍历比较了, 所以在新链表完全形成之后,再去进行最为正确!

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值