【发布时间】:2018-12-10 16:13:52
【问题描述】:
就 big-O 运行时而言,这两种数据结构似乎都处于“平均”情况:
-
O(1)插入/删除到开始和结束 -
O(n)插入/删除到任意索引中 -
O(1)查找开始和结束
循环缓冲区的优点:
-
O(1)查找某些任意索引而不是O(n) - 不需要创建节点,因此不需要在每次插入时动态分配
- 更好的缓存预测,更快的遍历
- 通过矢量化(例如使用
memmove)更快地删除以填补空白 - 通常需要更少的空间(因为在链表中,对于每个节点,您必须对指向下一个和/或上一个节点的指针进行排序)
链表的优点:
- 更容易将
O(1)插入/删除到某个特定位置(例如,可以在链接列表的中途获取它)。循环缓冲区可以做到,但更复杂 -
O(1)在最坏的情况下插入,与O(n)的循环缓冲区不同(当它需要增加缓冲区时)
根据这个列表,在我看来,循环缓冲区几乎在所有情况下都是更好的选择。我错过了什么吗?
【问题讨论】:
-
O(1) lookup instead of O(n) of some arbitrary index-- 呃,不。为什么?它仍然是 O(n),只是用于更小的(受约束的)n。如果您将链表与使用数组实现的循环缓冲区进行比较,那么您就是在比较苹果和橙子。 -
这里我们要解决问题了,几乎在所有情况下,集合都比数组更受欢迎,除了一个:集合不像数组那样具有固定大小。
-
对于您的第一条评论,循环缓冲区始终使用数组实现,根据定义:en.wikipedia.org/wiki/Circular_buffer。我不明白你为什么说它是苹果和橙子,它们都是数据结构。对于您的第二条评论,并假设您在 Java 中指的是“集合”和“数组”这些术语,它们都是可增长的集合,其中一个在内部使用数组。
-
these are both data structures.-- 当然,曼哈顿的草屋和公寓都是住宅。 -
我建议您将您的帖子与您遇到的特定软件开发问题联系起来。否则,这只是一个有资格结束的讨论,因为过于宽泛或基于意见。
标签: linked-list circular-buffer