0
点赞
收藏
分享

微信扫一扫

手把手教你手撕链表题-->《删除给定值val的所有节点》

DT_M 2022-04-08 阅读 55

该题呢,我给大家介绍两种解决的办法

首先大家先来看一下题目:

第一种方法:由于题目题目给的是head头指针,并没有给哨兵位指针。所以我们可以选择用三指针的方法来完成

首先第一种方法又分为两种情况:第一个的Val就是要删除的数据,以及第一个val不是要删除的数据。我们先来看下第一个不是val的情况

 

首先:我们定义一个指针cur来保存head指针,因为题目要求返回新的头节点,所以如果不对head保存而用head指针来进行遍历的话,那么我们就找不到头节点在哪个位置了。用next保存下一个节点的地址,方便找到val所在的节点的时候直接让val所在节点的前一个节点链接到next位置就可以。

其次:第一个数就为val也不需要太担心,我们只需要在上述第二种情况的代码里面加上一个if条件即可,第一个val就是要删除的数相当于链表所学过的头删。

struct ListNode* removeElements(struct ListNode* head, int val){
   struct ListNode* cur = head;  //保存一份head,用它来进行迭代(遍历)
   struct ListNode* prev = NULL;   //记录不是Val的位置
   while(cur != NULL )   //不为空表
   {
       if(cur->val == val)   
       {
           struct ListNode* next = cur->next;//保存当前节点的下一个节点,val等于val才用跳过当前节点cur
           if(prev == NULL)//第一种情况:第一个数据就为要删除的val 相当于头删
           {
               free(cur);//直接释放掉空间,让head挪动到下一个节点的位置,再让cur挪动到head的位置
               head = next;//让next位置成为头
               cur = head;//保存头的位置,由cur进行迭代
           }
           else  //第二种情况:第一个val不是要删除的数 这时候相当于第二种情况
           {
               free(cur); 
               cur = next;
               prev->next = cur;
           }
       }
       else  //没找到val 就让cur迭代走起来查找哪个节点的val为要删除的那个元素 prev走过的路径是把val已经删除的路径
       {
           prev = cur;//没找到把prec挪动到cur位置
           cur = cur->next;//cur指向下一个节点
       }
   }
   return head; //返回头指针主函数打印链表
}

温馨提示:通过上述代码走读,结合图上的三指针一步一步进行画图挪动,来感受这三个指针到底是怎么移动的。单看代码的话很难理解


 第二种方法:强行创建一个哨兵位(哨兵位并不拿来存放数据,但是哨兵位不等于NULL),用哨兵位等于上面的prev。

 

代码的具体实现其实跟第一种放大差别不大,我们就直接看代码了

struct ListNode* removeElements(struct ListNode* head, int val){
   struct ListNode* Bheard = (struct ListNode*)malloc(sizeof(struct ListNode)); //动态开辟一个哨兵位
   Bheard->next = head;//把哨兵位链接到链表中
   struct ListNode* cur = head;//保存一份head,用它来进行迭代(遍历)
   struct ListNode* prev = Bheard; //把不是val的节点链接起来
   while(cur != NULL ) //不为空表
   {
       if(cur->val == val) 
       {
           struct ListNode* next = cur->next;//保存当前节点的下一个节点,val等于val才用跳过当前节点
           prev->next = next;//绕过cur节点为val的位置,直接链接到下一个
           head = next;//
           free(cur);
           cur = next;
       }
       else
       {
           prev = cur;
           cur = cur->next;
       }
   }
   head = Bheard->next; //让head回到头部
   free(Bheard);//因为是动态开辟出来的所以要释放

   return head;
}

举报

相关推荐

0 条评论