1、删除链表元素
-
思路一
遍历链表,找出需要删除的,记住删除元素下一个位置,使其与需要删除的前一个链接起来,进而释放掉需要删除的节点
大致如图所示——这段代码很容易实现
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode*cur,*prev=NULL;
cur=head;
while(cur)
{
if((cur->val)==val)
{
prve->next=cur->next;
free(cur);
cur=prev->next;
}
else
{
prev=cur;
cur=cur->next;
}
}
return head;
}
但是明显,这个提交是错误的,我们忽略了一个极端问题
如果这个链表中数据需要全部进行删除,则我们需要对此代码进行修改,显然我们这里的head头部没有删除掉——
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode*cur,*prev=NULL;
cur=head;
while(cur)
{
if((cur->val)==val)
{
if(cur==head)
{
head=cur->next;
free(cur);
cur=head;
}
else{
prve->next=cur->next;
free(cur);
cur=prev->next;
}
}
else
{
prev=cur;
cur=cur->next;
}
}
return head;
}
则我们稍加判断,进而进行删除,则可做到完美。
-
思路二
我们可以将不是被删除数据的节点找到,进行尾插,这时候,需要更新链表的结尾
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode*cur=head,*tail=NULL;
head=NULL;
while(cur)
{
if(cur->val==val)
{
struct ListNode*del=cur;
cur=cur->next;
free(del);
del=NULL;
}
else
{
if(tail==NULL)
{
head=tail=cur;
}
else
{
tail->next=cur;
tail=tail->next;
}
cur=cur->next;
}
}
if(tail)
{
tail->next=NULL;
}
return head;
}
-
思路三
我们可以设置一个哨兵位头结点 进行尾插
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode*tail=NULL;
struct ListNode*phead=NULL;
struct ListNode*cur=head;
tail=phead=(struct ListNode*)malloc(sizeof(struct ListNode));
tail->next=NULL;
while(cur)
{
if(cur->val==val)
{
struct ListNode*del=cur;
cur=cur->next;
free(del);
del=NULL;
}
else
{
tail->next=cur;
tail=tail->next;
cur=cur->next;
}
}
tail->next=NULL;
struct ListNode*del=phead;
phead=phead->next;
free(del);
del=NULL;
return phead;
}