Skip to content

Latest commit

 

History

History
56 lines (36 loc) · 2.99 KB

3.linkedList.md

File metadata and controls

56 lines (36 loc) · 2.99 KB

链表

  • 动态数组有个明显的缺点:可能会造成内存空间的大量浪费,能否用到多少就申请内存?

  • 链表可以办到这一点

  • 链表是一种链式存储的线性表,所有元素的内存地址不一定是连续的

  • https://visualgo.net/zh 数据结构和算法动态可视化

快慢指针

  • 快指针走两步,慢指针走一步,如果有环存在,它们两个一定会相遇。因为模拟一下就知道,它们之间得距离是每次递减1,所以一定会相遇。

虚拟头结点

  • 有时候为了让代码更加精简,统一所节点的处理逻辑可以在最前面增个虚拟头结点(不存储数据)

均摊复杂度

  • 经过连续的多次复杂度比较低的情况后,出现个别复杂度比较高的情况

动态数组的缩容

  • 如果内存使用比较紧张,动态数组有多的剩余空间可以考虑进行缩容操作,比如剩余空间占总容量的一半时,就进行缩容

  • 如果扩容倍数、缩时机设计不得当,有可能会导致复杂度震荡

  • 复杂度震荡的解决办法:让缩容和扩容的倍数相乘不要等于

动态数组 vs 单向链表

  • 粗略对比一下删除操作的数量
    • 单向链表 1 + 2 + 3 + ... + n = ((1 + n) * n) / 2 再除以 n ,最后是 1/2 + n/2 => O(n)。
    • 双向链表 (1 + 2 + 3 + ... + n/2) * 2 = (((1 + n/2) * n/2) / 2 )* 2 再除以 n ,最后是 1/2 + n/4 => O(n)
    • 把可能的操作次数全部加起来,然后除以数据规模,得出平均复杂度。双向链表计算两个方向,所以乘以 2。
    • 虽然双向链表也是 O(n),但是看到它是 n/4 ,而 单向链表是 n/2,所以双向链表平均操作次数比单向链表少了一半。

双向链表 vs 动态数组

  • 动态数组 :开辟、销毁内存空间的次数相对较少,但可能造成浪费(以通过缩容解决)

  • 双向链表 :开辟、销毁内存空间的次数相对较多,但不会造成浪费

  • 如果频繁在 尾部 进行 添加 、删除 操作, 动态数组 、双向链表 均可选择

  • 如果频繁在 头部 进行 添加 、删除 操作,建议选择使用 双向链表

  • 如果有频繁的( 在任意位置 )添加 、删除 操作,建议选择使用 双向链表

  • 如果有频繁的 查询 操作(随机访问),建议选择使用 动态数组

  • 有了双向链表,单向链表是否就没任何用处?并非如此,在哈希表的设计中就用到了单向链表

链接