【问题标题】:C# Datastructure with SortedDictionary() and node.Next() functionality?具有 SortedDictionary() 和 node.Next() 功能的 C# 数据结构?
【发布时间】:2011-05-09 08:01:47
【问题描述】:

如何构造/获取具有以下功能的数据结构:

  • 存储(键,值)节点,键实现IComparable。
  • 快速 (log N) 插入和检索。
  • 从任何节点检索下一个更高/下一个更低节点的快速 (log N) 方法。 [示例:如果 插入的键值为 (7,cat), (4,dog),(12,ostrich), (13,goldfish) 那么如果 keyVal 引用 (7,cat), keyVal.Next() 应该返回对 ( 12、鸵鸟)]。

使用来自任意键的枚举器的解决方案当然也足够了。请注意,标准的 SortedDictionary 功能是不够的,因为只能返回整个集合的枚举数,这使得查找 keyVal.next 最多需要 N 次操作。

是否可以为自行实现的平衡二叉搜索树(红黑树)配备 node.next() 功能?这样做有什么好的参考吗?有没有更省时的编码解决方案?

【问题讨论】:

  • 同一主题还有很多其他问题,但没有一个能解决我的问题
  • @willem 我不明白。只有一个枚举器并执行.MoveNext().MoveNext()、...还不够吗?
  • @Oscar 如果您反复使用 .MoveNext() 从某个当前节点查找下一个节点(只需遍历整个集合,直到找到当前节点,然后再迭代一次),这将非常耗时。我想要下一个节点快
  • @willem hmm.. 这取决于如何在 SortedDictionary 类上实现该功能。它应该是 O(n) 以排序顺序产生所有元素,所以每次你做 .MoveNext() 时都会是 O(1)
  • @willem 我在不超过两天的时间内完成了它,尽管我记得我必须在几天前修复一个错误,因为它不是 100% 平衡的。 Introductions to Algorithms 一书是一个很好的参考。它很好地解释了每次旋转。我建议你实施它。然后,您可以使其通用并为每个具有类似要求的项目提供一份副本:)

标签: c# data-structures sorteddictionary


【解决方案1】:

我曾经有类似的要求,但找不到合适的东西。所以我实现了一个 AVL 树。这里有一些建议来考虑性能:

  1. 不要使用递归遍历树(插入、更新、删除、下一步)。最好使用堆栈数组来存储平衡操作所需的到根的路径。
  2. 不存储父节点。所有的操作都会从根节点开始,往下走。如果仔细实施,则不需要父母。
  3. 为了找到现有节点的 Next() 节点,通常首先调用 Find()。由此产生的堆栈,应该被重用于 Next() 。

通过遵循这些规则,我能够实现 AVL 树。即使对于非常大的数据集,它也能非常有效地工作。我愿意分享,但它需要一些修改,因为它不存储值(非常容易)并且不依赖于 IComparable 而是依赖于 int 的固定键类型。

【讨论】:

  • 如果您愿意分享:太好了!修改似乎很容易。无论如何,感谢您的建议。
【解决方案2】:

PowerCollections 中的 OrderedDictionary 提供了一个“在键处或之前获取迭代器”函数,该函数需要 O(log N) 时间来返回第一个值。例如,这使得扫描接近 5000 万个项目集中间的 1000 个项目变得非常快(使用 SortedDictionary 需要猜测从开始或结束开始,这两者都是同样糟糕的选择,需要迭代器大约 2500 万个项目)。 OrderedDictionary 只需迭代 1,000 个项目即可。

OrderedDictionary 中存在一个问题,因为它使用了在 32 位进程中迭代 5000 万个项目集时会导致 O(n^2) 性能和内存不足的情况。有一个非常简单的解决方法,我稍后会记录。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    相关资源
    最近更新 更多