目录
3. 给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
1. 删除链表中等于给定值 val 的所有结点
基础题
小tips:默认链表是不带哨兵位的。
1.编译出错是语法问题
2.执行出错:
- 走读代码(跟着逻辑)画图分析
- 找不到错误可以调试 画图+vs调试,用报错的那个测试
接口型oj
1.1第一种方法:
这道题没有使用二级指针
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode* prev = NULL;
struct ListNode* cur = head;
while(cur)
{
if(cur->val == val)
//头删--特殊情况
if(cur == head)
{
head = cur->next;
free(cur);
cur = head;
}
else
{
//删除
prev->next = cur->next;
free(cur);
cur = prev->next;
}
else//没有与val相等的值就接着往下走
{
prev = cur;//将cur赋值给prev
cur = cur->next;//cur接着下一个
}
}
return head;//回到头结点
}
1.2第二种方法:
给两个指针,tail最开始置成空,去标记这个尾
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode * tail = NULL;
struct ListNode* cur = head;
head = NULL;
while(cur)
{
if(cur->val == val)
{
struct ListNode* del = cur;
cur = cur->next;
free(del);//释放与val相等的结点
}
else
{
//尾插
//遍历原链表,把不是val的结点拿出来尾插到新链表
if(tail == NULL)
{
head = tail = cur;
}
else
{
tail->next = cur;
tail = tail->next;
}
cur = cur->next;
}
}
if(tail)
tail->next = NULL;
return head;
}
1.3改善代码
简化代码不用考虑头删的情况,但释放的时候也得处理
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode* tail = NULL;
struct ListNode* cur = head;
//带哨兵位的头结点(简化尾插)
head = tail = (struct ListNode*)malloc(sizeof(struct ListNode));
tail->next = NULL;
while(cur)
{
if(cur->val == val)
{
struct ListNode* del = cur;
cur = cur->next;
free(del);
}
else
{