链式结构与顺序结构的区别

本文对比了ArrayList和LinkedList在底层实现、随机访问速度、内存占用以及插入删除操作的时间复杂度,指出LinkedList在头插头删上有优势,但其他情况下ArrayList更高效,同时讨论了Java设计中的不足。
摘要由CSDN通过智能技术生成

![[Pasted image 20231108144759.png]]
注意:

  • ArrayList 底层是一个数组,可以进行随机访问,当使用随机访问进行读写时,速度是比较快的

    • 随机访问:按照 “下标” 访问,称为 “随机访问”,事先不知道要访问哪一个,我们 随机地 访问,它的开销和耗时都很低且差不多,这就叫随机访问。随机访问不是查找,这是两种操作
    • 查找使用的是 indexOf() 这样的方法,按照元素的值进行查找,这个过程要遍历 ArrayList,时间复杂度为 O(N)
  • 所以说,ArrayList 尾插/删除速度比较快;头插/中间插入/删除 这些操作就比较慢(涉及元素搬运)

  • LinkedList 底层是一个链表,不能进行随机访问

  • 它进行 头插/头删/尾插/尾删 这些操作的时间复杂度为 O(1)

  • 进行 查找/中间位置的插入/删除,时间复杂度都是 O(N),因为这些操作涉及到了查找

  • 所以说,LinkedList 相比与 ArrayList 唯一的优势,就是能 快速头插头删(这在 实现队列时很有用),除此之外,其他的各个方面,都是 ArrayList 更优秀


问题

问题1:用 LinkedList,是否遍历更快呢?

答:当然不是,链表访问下一个元素,要通过 next 这样的引用,相比于顺序表直接的 下标++ 操作,多了一次 内存访问 的过程。

  • 下标++ 这种操作,通常都是在 寄存器 中完成,所以这种操作要更快一些

问题2:使用 LinkedList 是否更节省内存呢?因为 ArrayList 是需要预分配空间的

答:当然也不是,链表的每个结点都要有额外的空间存储 “指针域”,空间到底能不能省内存,要打上一个问号


问题3:使用 LinkedList,在中间位置插入删除,为什么时间复杂度是 O(N)?

答:这件事,是 Java 的接口没有设计好,属于设计失误,LinkedList 通过 add(元素,下标) 进行插入,这个根据 下标 找位置的过程就是链表遍历的 O(N) 操作


说明:

  • 问题3 与 C++ 相比 ,C++ 设计的就更科学,C++的链表 std::list 插入操作 insert(值,迭代器),C++的迭代器功能要强大很多,应用范围也很广,这个迭代器就已经 显式 的告诉你插入删除的位置了,此时按照指定位置进行插入删除就是 O(1) 操作了
  • 由于 list 这样的数据结构地位过于尴尬,以至于其他很多语言中是不提供这样的数据结构的
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行舟Yi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值