力扣203题:移除链表元素及代码实现分析
在链表操作中,删除指定元素是一个常见的任务。本文将详细解析两段C语言代码,它们都实现了从单链表中删除指定值的节点的功能。理解这两种方法,对于掌握链表操作和算法设计很有帮助。
单链表的结构定义
在开始分析代码之前,先看一下单链表节点的结构定义:
struct ListNode {int val;struct ListNode *next;
};
每个节点包含一个整数值 val 和一个指向下一个节点的指针 next 。
第一种实现方法
代码展示
struct ListNode* removeElements(struct ListNode* head, int val)
{struct ListNode*newcode=NULL;struct ListNode*temp=NULL;struct ListNode*cur=head;while(cur){if(cur->val!=val){if(temp==NULL){newcode=temp=cur;}else{temp->next=cur;temp=temp->next;}cur=cur->next;}else{struct ListNode*next=cur->next;free(cur);cur=next;}}if(temp)temp->next=NULL;return newcode;
}
代码解析
初始化指针: newcode 用于指向新链表的头节点, temp 用于遍历新链表, cur 用于遍历原链表。
遍历原链表:使用 while 循环遍历链表, cur 依次指向每个节点。
判断节点值:如果当前节点的值不等于要删除的值 val ,则将其加入新链表。如果新链表为空,将 newcode 和 temp 都指向当前节点;否则,将当前节点接到 temp 的后面,并更新 temp 。
删除节点:如果当前节点的值等于 val ,保存下一个节点的指针,释放当前节点,然后将 cur 指向下一个节点。
处理链表末尾:遍历结束后,将新链表的最后一个节点的 next 设为 NULL ,防止出现野指针。
返回结果:返回新链表的头节点 newcode 。
第二种实现方法
代码展示
struct ListNode* removeElements(struct ListNode* head, int val)
{struct ListNode*pre=NULL;struct ListNode*tmp=head;while(tmp){if(tmp->val!=val){pre=tmp;tmp=tmp->next;}else{if(pre==NULL){tmp=head->next;free(head);head=tmp;}else{pre->next=tmp->next;free(tmp);tmp=pre->next;}}}return head;
}
代码解析
初始化指针: pre 用于指向当前节点的前一个节点, tmp 用于遍历链表。
遍历链表:使用 while 循环遍历链表, tmp 依次指向每个节点。
判断节点值:如果当前节点的值不等于 val ,则将 pre 指向当前节点,然后 tmp 指向下一个节点。
删除节点:如果当前节点的值等于 val ,分两种情况处理。如果 pre 为空,说明当前节点是头节点,更新头节点并释放原头节点;否则,将 pre 的 next 指向 tmp 的下一个节点,释放 tmp ,然后将 tmp 指向 pre 的下一个节点。
返回结果:返回更新后的头节点 head 。
总结
这两种方法都能有效地从单链表中删除指定值的节点。第一种方法通过构建新链表来实现,逻辑较为清晰;第二种方法则直接在原链表上进行删除操作,更节省空间。在实际应用中,可以根据具体需求选择合适的方法。理解和掌握这些链表操作技巧,有助于提升编程能力和解决实际问题的能力。