代码随想录二刷 |链表 | 链表总结

理论基础

每一个节点都有两部分组成,一个是数据域(存放节点的数据)一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向NULL,入口处的节点又称空指针。

分类

单链表

每一个节点都有两部分组成,一个是数据域(存放节点的数据)一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向NULL,入口处的节点又称空指针。

双链表

一个节点有两个指针域,分别指向前一个节点和后一个节点,它可以双向查询。

环形链表

头节点和尾节点相连

存储方式

链表的节点在内存中是散乱分布在内存的某地址上,分配机制取决于操作系统的内存管理

链表的定义

结构体中至少需要包括数据,指向下一个节点的指针以及节点的构造函数。

如果不定义函数,不能在定义链表时初始化

struct ListNode{
	int val;
	ListNode* next;
	ListNode(int x) : val(x), next(nullptr) {}
};

链表操作

删除链表节点

前一节点跳过该节点指向下一节点

添加链表节点

前一节点指向该节点,该节点指向下一节点

性能分析

插入/删除(时间复杂度)查询(时间复杂度)适用场景
数组O(n)O(1)数据量固定,频繁查询,较少增删
链表O(1)O(n)数据量不固定,较少查询,频繁增删

移除链表元素

在原链表上移除

  • 移除头节点:将头节点设置为后一个节点,并且回收头节点
  • 其他节点:将前一个节点的指针指向下一个节点,并且回收该节点

虚拟头节点移除

设置虚拟头节点,从虚拟头节点开始遍历,删除每一个节点都是使用前一个节点的指针指向下一个节点,并且删除当前节点,当遍历结束,返回虚拟头节点的后一个节点

设计链表

  • 设置虚拟头节点,方便统一操作头节点
  • 获取链表的第几个元素,此时应该取到正对的那个节点,因此cur应该设置为head而不是dummyHead,并且由于index从0开始,因此index不能大于size() - 1
  • 在指定index前插入和删除,需要都遍历到目标节点的前一个节点,因此cur应当从dummyHead开始
  • 插入一个节点index可以是size,因为实际会取到左后一个节点并且在最后一个节点后边插入,删除节点index不能是size,因为没有size这个节点

反转链表

双指针

定义一个cur指针指向头节点,再定一个pre指针初始化为NULL。首先要把cur->next节点用temp指针保存一下,也就是保存一下这个节点,将cur->next指向pre,此时已经反转了一个节点,然后pre = cur,cur = pre

递归

  • 从前向后:类似于双指针只是把pre = cur,cur = pre这个部分用递归实现
  • 从后向前:先遍历到最后,然后利用cur -> next -> next = cur进行翻转

两两交换链表节点

dummyHead指向头节点,cur指针指向dummyHead,再定义两个指针用于保存节点:
tmp = cur -> next;
tmp1 = cur -> next -> next -> next

  • 第一步:cur -> next = cur -> next -> next
  • 第二步:cur -> next -> next = tmp;
  • 第三步:cur -> next -> next -> next = tmp1;

交换完两个以后将cur向后移动两位

移除链表的倒数第 N 个节点

使用双指针,一个指针先走N步,然后两个指针一起向后遍历,当前边的指针先到达尾节点,后边的指针位于第N节点,之后将该节点的 -> next -> next赋给next,完成对节点的删除

前边的指针先走N步后,还应该再走一步,保证后边的指针实际是在第N个节点的前一个,从而方便删除

链表相交

  • 本题要求的实际是两个链表首个交点的指针,交点比较的是指针相同而不是数值相等
  • 将两个链表结尾靠在一起,然后一个指针指向短链表的开始,一个指向长链表与短链表开头对齐的地方
  • 两个指针一起向后遍历,直到找到两个指针相同的节点,返回该节点即可

环形链表II

需要解决两个问题:

  • 如何判断链表有环
  • 如果有环,如何找到环状入口节点

可以使用快慢指针法,分别定义fast和slow指针,从头节点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果fast和slow指针在途中相遇,说明这个链表有环

在这里插入图片描述

相遇时慢指针走过了x + y,快指针走过了x + y + n * (y + z),因为快指针一步走两个节点,是慢指针的两倍,假设快指针只多走了一圈,那么 n = 1,从而 x = y,也就是一个指针从头走,一个从交点走,两个指针第一次相遇的位置即为环形入口节点。

本文参考录友@海螺人的总结思维导图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值