当前位置:   article > 正文

【链表OJ题】移除链表元素

【链表OJ题】移除链表元素

力扣链接:203. 移除链表元素 - 力扣(LeetCode)

这道题目涉及到删除节点,回忆下链表的结构,每个链表的节点除了存储数据外,还存储了下一个节点的地址,也就是说我们删除掉一个节点的时候,我们首先要找到这个节点的上一个节点,这里我们叫它为prev,接着还需要它的下一个节点,我们叫它为next。因为链表是通过一个一个的next指针链接的,如果这里直接把要删除的节点释放掉,就访问不到它后面的节点了,因为这里涉及到野指针问题。所以在删除节点前,要让这个节点的prev的next指向这个节点的next。

这道题目可以用三种方法,我们首先讲解第一种尾插的方法。

方法一:取不需要删除的节点依次尾插

这里的cur在2那里

这里的cur在3那里

这种方法需要在最后额外让tail的next置为NULL(前提是tail不为空),防止出现野指针的情况。

还有就是尾插第一个的时候其实是让newhead和tail都等于当前的cur。

  1. struct ListNode* removeElements(struct ListNode* head, int val)
  2. {
  3. struct ListNode* newhead = NULL;
  4. struct ListNode* tail = NULL;
  5. struct ListNode* cur = head;
  6. while (cur)
  7. {
  8. if (cur->val != val)
  9. {
  10. if (newhead)
  11. {
  12. tail->next = cur;
  13. tail = cur;
  14. }
  15. else
  16. newhead = tail = cur;
  17. cur = cur->next;
  18. }
  19. else
  20. {
  21. // 释放节点前保存下一个节点
  22. struct ListNode* tmp = cur->next;
  23. free(cur);
  24. cur = tmp;
  25. }
  26. }
  27. if (newhead)
  28. tail->next = NULL;
  29. return newhead;
  30. }

方法二:双指针,需要删除时创建第三个

  1. struct ListNode* removeElements(struct ListNode* head, int val)
  2. {
  3. struct ListNode* prev = NULL;
  4. struct ListNode* cur = head;
  5. struct ListNode* next;
  6. while (cur)
  7. {
  8. if (cur ->val != val)
  9. {
  10. prev = cur; // prev始终保持在cur的前一个节点
  11. cur = cur->next;
  12. }
  13. else
  14. {
  15. next = cur->next;
  16. free(cur);
  17. cur = next;
  18. if (prev == NULL) // 当第一个节点就要删除时更新头节点
  19. head = next;
  20. else
  21. prev->next = next;
  22. }
  23. }
  24. return head;
  25. }

方法三:增加哨兵

这种方法与方法2类似,只是增加了哨兵位,可以少判断一次prev为不为空

  1. struct ListNode* removeElements(struct ListNode* head, int val)
  2. {
  3. struct ListNode* phead = (struct ListNode*)malloc(sizeof(struct ListNode));
  4. struct ListNode* cur = head;
  5. struct ListNode* prev = phead;
  6. struct ListNode* next = NULL;
  7. while (cur)
  8. {
  9. if (cur ->val != val)
  10. {
  11. prev->next = cur;
  12. prev = cur;
  13. cur = cur->next;
  14. }
  15. else
  16. {
  17. next = cur->next;
  18. free(cur);
  19. cur = next;
  20. prev->next = next;
  21. }
  22. }
  23. // 防止头节点为空
  24. prev->next = NULL;
  25. // 不要忘记释放malloc出来的哨兵位
  26. head = phead->next;
  27. free(phead);
  28. return head;
  29. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/585987
推荐阅读
相关标签
  

闽ICP备14008679号