代码随想录【链表】---->链表移除
链表的理论基础:
链表是通过指针串联起来的顺序存储结构,链表的每一个元素称为节点,每一个节点都有数据域和指针域(指向下一个节点),最后一个节点的指针域为NULL指针,链表第一个元素的指针称为头节点
关于更详细的请看这篇文章syseptember的个人博客:无头单向链表
203. 移除链表元素
题目LeetCode203. 移除链表元素
思路
链表删除元素是通过变换指针指向
而实现的,如下链表 1 4 2 4举例
tips:使用C/C++删除链表节点时需要手动释放删除的节点内存
直接删除
删除一个节点时需要将该节点
的前一个结点的指针域
指向该节点的下一个节点
但是第一个节点不存在前一个结点,所以直接删除的话需要分两种情况讨论
- 删除的是头节点
- 删除的不是头节点
代码
//直接移除
struct ListNode* removeElements(struct ListNode* head, int val){typedef struct ListNode ListNode;ListNode* tmp;//判断是否需要头删while (head && head->val == val){tmp = head;//记录删除位置head = head->next;free(tmp);//释放删除位置}//删除的元素不在头部ListNode* cur = head;//保证cur和cur->next不为空while (cur && (tmp = cur->next)){if (cur -> next -> val == val){cur->next = cur->next->next;//前节点的指针域指向后一个节点free(tmp);//释放删除节点}else {cur = cur -> next;}}return head;
}
虚拟头节点
在删除过程中,因为头节点没有前一个结点所以我们需要分类讨论,如果我们给头节点前面加上一个节点,那么此时头节点也可以后非头节点进行统一的处理的,新加上的节点为虚拟头节点
代码
//虚拟头节点
struct ListNode* removeElements(struct ListNode* head, int val){typedef struct ListNode ListNode;ListNode* dummyHead = (ListNode*)malloc(sizeof(ListNode));dummyHead->next = head;ListNode* cur = dummyHead;ListNode* tmp;//直到遍历到尾节点while (cur->next){if (cur->next->val == val){tmp = cur->next;cur->next = cur->next->next;free(tmp);}else {cur = cur->next;}}//不要返回head,如果头删的话head已经被释放了return dummyHead->next;
}