赞
踩
力扣链接:203. 移除链表元素 - 力扣(LeetCode)
这道题目涉及到删除节点,回忆下链表的结构,每个链表的节点除了存储数据外,还存储了下一个节点的地址,也就是说我们删除掉一个节点的时候,我们首先要找到这个节点的上一个节点,这里我们叫它为prev,接着还需要它的下一个节点,我们叫它为next。因为链表是通过一个一个的next指针链接的,如果这里直接把要删除的节点释放掉,就访问不到它后面的节点了,因为这里涉及到野指针问题。所以在删除节点前,要让这个节点的prev的next指向这个节点的next。
这道题目可以用三种方法,我们首先讲解第一种尾插的方法。
这里的cur在2那里
这里的cur在3那里
这种方法需要在最后额外让tail的next置为NULL(前提是tail不为空),防止出现野指针的情况。
还有就是尾插第一个的时候其实是让newhead和tail都等于当前的cur。
- struct ListNode* removeElements(struct ListNode* head, int val)
- {
- struct ListNode* newhead = NULL;
- struct ListNode* tail = NULL;
- struct ListNode* cur = head;
-
- while (cur)
- {
- if (cur->val != val)
- {
- if (newhead)
- {
- tail->next = cur;
- tail = cur;
- }
- else
- newhead = tail = cur;
- cur = cur->next;
- }
- else
- {
- // 释放节点前保存下一个节点
- struct ListNode* tmp = cur->next;
- free(cur);
- cur = tmp;
- }
- }
- if (newhead)
- tail->next = NULL;
-
- return newhead;
- }
- struct ListNode* removeElements(struct ListNode* head, int val)
- {
- struct ListNode* prev = NULL;
- struct ListNode* cur = head;
- struct ListNode* next;
-
- while (cur)
- {
- if (cur ->val != val)
- {
- prev = cur; // prev始终保持在cur的前一个节点
- cur = cur->next;
- }
- else
- {
- next = cur->next;
- free(cur);
- cur = next;
- if (prev == NULL) // 当第一个节点就要删除时更新头节点
- head = next;
- else
- prev->next = next;
- }
- }
- return head;
- }
这种方法与方法2类似,只是增加了哨兵位,可以少判断一次prev为不为空
- struct ListNode* removeElements(struct ListNode* head, int val)
- {
- struct ListNode* phead = (struct ListNode*)malloc(sizeof(struct ListNode));
- struct ListNode* cur = head;
- struct ListNode* prev = phead;
- struct ListNode* next = NULL;
-
- while (cur)
- {
- if (cur ->val != val)
- {
- prev->next = cur;
- prev = cur;
- cur = cur->next;
- }
- else
- {
- next = cur->next;
- free(cur);
- cur = next;
- prev->next = next;
- }
- }
- // 防止头节点为空
- prev->next = NULL;
-
- // 不要忘记释放malloc出来的哨兵位
- head = phead->next;
- free(phead);
-
- return head;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。