【问题标题】:Linked Ordered Set or Ordered Linked List?链接有序集还是有序链表?
【发布时间】:2022-02-02 09:43:33
【问题描述】:

我需要一个高效的数据结构来在实时(每秒多达一百次插入、删除或更新)服务器上存储大量(数百万)条记录。

它的客户需要能够抓取大量数据,从某个点开始进行排序,能够滚动(即获取他们最初获得的记录之前和之后的记录)并接收实时更新。

最初,我考虑了某种形式的链接有序集和一些索引,但是即使记录在它们具有 id 的意义上是唯一的,它们的字段值也不是。只需在每个节点中插入多条记录即可解决冲突,但似乎不正确。

我想出的另一个解决方案是一个带有索引的链接集,它通过插入删除和更新来保持排序。其中的大 O 不是 O(log n) 而是 O(n),但我猜如果我还有索引,它会大大加快这个过程吗?还是二分查找要插入的地方?但不要认为我可以使用列表。

鉴于我需要客户端接收有关此数据结构状态的实时更新,什么是最有效的解决方案以及哪种解决方案最好?

代码将使用 Java

【问题讨论】:

  • 我认为双向链表适合prev和next指针指向当前集合之前和prev的集合,对于这里的集合,您可以使用自平衡bst,例如AVL树插入/删除成本将是 O(logn)?

标签: java list algorithm data-structures set


【解决方案1】:
  1. 数百万条记录 -> 首先估计您是否希望/可以将所有数据保存在 RAM 中。

  2. 看看b-tree

    Algorithm Average Worst case
    Space O(n) O(n)
    Search O(log n) O(log n)
    Insert O(log n) O(log n)
    Delete O(log n) O(log n)

【讨论】:

    【解决方案2】:

    Java 中,这些类型的需求通常通过使用TreeMap (如数据库索引)来解决。 TreeMap 接口不是为此特别设计的,所以有一些技巧:

    • 您的记录对象应该实现一个Key 接口或基类,它只公开排序字段和ID。该接口不应扩展Comparable
    • 你的记录对象会同时是TreeMap中的key值,每条记录都会映射到自己,但是Key接口会作为key,所以映射的类型是@ 987654326@。请记住,每个put 都应该是put(record,record) 的形式
    • 创建TreeMap 时,请使用采用自定义比较器的构造函数。传递一个比较器,使用排序字段和 ID 比较 Keys,这样就不会有重复项
    • 要在地图中搜索,您可以使用Key 接口的其他实现——您不必使用完整的记录。但是,由于调用者无法提供 ID,因此您无法使用 TreeMap.get() 查找与排序字段匹配的记录。使用 ID=0 和 TreeMap.ceilingEntry 的键来获取具有 >= 键的第一条记录,然后检查排序字段以查看它们是否匹配。

    请注意,如果您需要对不同字段进行多次排序,您可以让您的记录实现多个 Key 接口,并将它们放在多个映射中。

    【讨论】:

      猜你喜欢
      • 2010-09-14
      • 1970-01-01
      • 2011-01-07
      • 2013-02-02
      • 1970-01-01
      • 2015-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多