目录
前言
一.思路
1)遍历原链表,找到值为 val 的节点并释放
2)创建新链表
二.代码实现
1)大胆去try一下思路
2)竟然报错了?!
3)完善之后的成品代码
搭配食用更佳哦~~
数据结构之单单单——链表-CSDN博客
数据结构之单链表的基本操作-CSDN博客
前面学了单链表的相关知识,我们来尝试做一下关于顺序表的经典算法题~
前言
移除链表元素是力扣上一道简单题,适合刚学过单链表的我们更好的理解链表相关知识~当然最好大家可以先去力扣上自己 try 一下~~
203. 移除链表元素 - 力扣(LeetCode)https://leetcode.cn/problems/remove-linked-list-elements/
一.思路
题干很简单,给你一个链表里面有一堆数据,再给你一个 val ,要找出链表里所有等于 val 的值并删除,生成不含 val 的新链表。
1)遍历原链表,找到值为 val 的节点并释放
我们需要创建两个指针变量 head 和 pcur指向链表的头节点并且遍历链表,pcur 遍历到 val 值的时候停下,此时我们需要删除这个节点,但我们不能直接删除,和顺序表不同链表每个节点内置下一个节点的指针指向,如果直接删除链表就断了没法继续遍历,所以我们还需要再定义个变量 prev 在 pcur 前面,当 pcur 找到 val 时候,将 prev 指针指向下一个值不为 val 的节点,然后将 pcur 指向的值释放掉,所以我们还需要创建一个指向pcur 后面的变量 next,依次往后遍历数组,直到所有的 val 都被释放。
2)创建新链表
顾名思义,我们在原链表的基础上,在新建一个空链表待用,依旧创建指针变量遍历原链表,找出值不为 val 的节点并存储到新链表里,遍历完成就可以得到所需要的链表了。
我们需要给新链表创建两个头尾指针 newHead 和 newTail 来遍历新链表,注意此时新链表应该是空 NULL ,如下图所示:
然后我们可以开始遍历原链表,需要注意的是,因为新链表为空所以既是头节点又是尾节点 ,当遍历一个节点到新链表之后,后面遍历的节点应尾插在尾节点的下一个节点插入,也就是 newTail 的 next 指针插入,此时链表有两个节点了,所以 newTail 应指向下一个节点的位置:
当 pcur 遇到值为 val 的点的时候就跳过继续遍历下一个节点 。最终当 pcur 遍历完成指向为空的时候就得到新链表:
二.代码实现
1)大胆去try一下思路
当我们理清思路的时候就可以开始尝试编写代码 :
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
typedef struct ListNode ListNode;
struct ListNode* removeElements(struct ListNode* head, int val) {//创建一个空链表ListNode* newHead, *newTail;newHead = newTail = NULL;//遍历原链表ListNode* pcur = head;while(pcur){//找出值不为val的节点,尾插到新链表里if(pcur->val != val){//链表为空if(newHead == NULL){newHead = newTail = pcur;}else{//链表不为空newTail->next = pcur;newTail = newTail->next;}}pcur = pcur->next;}return newHead;
}
2)竟然报错了?!
当我们完成编写之后尝试第一次运行,我们会惊人的发现————解答出错了!
输出的结果显示我们没有将本该被删除的 val 删除干净,为什么最后一个 val 的没删除呢?我们回头去看思路,我们注意一下在新链表的最后一个节点——也就是数值为5的那个节点,那里都存储着什么呢?一个是存储的 data = 5 ,还有一个指针——一个指针?这个指针是指向哪里的呢?因为这个节点是从原链表插过来的,那显而易见这个指针是指向下一个节点,也就是原链表最后一个值为 val 的节点,所以我们需要完善一下我们的代码,将最后一次 newTail 的 next 指针指为空,这样就可以避免让我们的新链表的尾节点指向原链表的最后一个节点了。
3)完善之后的成品代码
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
typedef struct ListNode ListNode;
struct ListNode* removeElements(struct ListNode* head, int val) {//创建一个空链表ListNode* newHead, *newTail;newHead = newTail = NULL;//遍历原链表ListNode* pcur = head;while(pcur){//找出值不为val的节点,尾插到新链表里if(pcur->val != val){//链表为空if(newHead == NULL){newHead = newTail = pcur;}else{//链表不为空newTail->next = pcur;newTail = newTail->next;}}pcur = pcur->next;}if(newTail)newTail->next = NULL;return newHead;
}
这次就完美运行成功啦~~
下一篇会接着将另一道有关链表的算法题~~
🎈🎈完结撒花🎈🎈