代码随想录【链表】---->链表移除

链表的理论基础:
链表是通过指针串联起来的顺序存储结构,链表的每一个元素称为节点,每一个节点都有数据域和指针域(指向下一个节点),最后一个节点的指针域为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;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_74278159/article/details/130029399
今日推荐