【问题标题】:When would a linked list be preferred over a circular buffer?什么时候链表比循环缓冲区更受欢迎?
【发布时间】: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


【解决方案1】:

MCS 锁是目前最具可扩展性的锁设计之一。线程使用原子比较和交换来尝试获取锁。如果它有效,它就完成了。如果它不起作用,线程使用原子交换将自己排入等待者列表的尾部。

没有锁或更复杂的原子指令使用的循环缓冲区无法做类似的事情。

【讨论】:

    猜你喜欢
    • 2017-08-04
    • 1970-01-01
    • 2019-06-11
    • 2020-10-25
    • 2015-11-13
    • 2012-12-06
    • 1970-01-01
    • 2012-11-16
    • 1970-01-01
    相关资源
    最近更新 更多