【问题标题】:C# - Binary search a (sorted) DictionaryC# - 二进制搜索(排序的)字典
【发布时间】:2017-04-22 12:21:14
【问题描述】:

我有一个按字母顺序排列的记录文件:

  • 安德鲁 d432
  • 本 x127
  • ...
  • ...
  • 扎克 b332

第一个字段是人名,第二个字段是一些 id。读取文件后,我无需对数据进行任何更改。

我想将每条记录视为键值对,其中人名是键。我不知道使用哪个类来访问记录(尽可能快)。 Dictionary 没有二进制搜索。另一方面,据我了解,SortedListSortedDictionary 仅应在我需要插入/删除数据时使用。

编辑:为了澄清,我说的是简单地访问记录,例如:

x = MyDic[Zac]

【问题讨论】:

  • 字典将具有恒定的时间访问,因为它将使用键的哈希作为值的索引。假设您想要精确匹配查找,则不需要二进制搜索。
  • 困惑。你有一本字典(应该)为你提供 O(1) 访问你想要的任何键/值(如果它存在的话)。你到底想搜索什么?
  • 如果您的密钥都是唯一的 - 那么Dictionary<string, string> 是适合您的数据结构,但您根本不需要二进制搜索。如果您的键不是唯一的,那么您可能需要Dictionary<string, List<string>>,对于每个唯一键,您将在其中存储 id 列表 - 同样您不需要二进制搜索,字典将搜索恒定时间。
  • 当您使用字典时,一旦您拥有 Key 值,您就可以直接获取该值,例如在您的情况下,命令 MyDictionary["Zac"] 应该返回“b332”。您到底想进行什么样的搜索?
  • @Bohoo 字典在大多数情况下会比对已排序数组(如果数组的大小相对较大)的二进制搜索更快,因为它需要 O(1) 而不是 O(log(n))。

标签: c# .net dictionary search


【解决方案1】:

一般来说字典查找会比集合的二分查找更快。有两种具体情况不属实:

  1. 如果列表很小(在我的测试中少于 15 个(可能低至 10 个)项),那么计算哈希码和通过字典查找的开销将比对数组的二进制搜索要慢。但超过 15 个项目,字典查找胜过二分查找。
  2. 如果有很多散列冲突(由于散列函数错误或具有高负载因子的字典),则字典查找速度会减慢。如果它真的很糟糕,那么二进制搜索可能会击败字典查找。

在使用 .NET 字典保存各种数据的 15 年中,我从未见过 #2 在使用标准 String.GetHashCode() 方法处理真实数据时会出现问题。我遇到麻烦的唯一一次是我创建了一个错误的 GetHashCode() 方法。

【讨论】:

  • 当项目正好位于集合的中间时,即使是#1 似乎也不太可能作为唯一一次在二分搜索中执行一次。否则,我预计多次搜索的成本会高于哈希码计算的成本。
  • @DStanley:在我的测试中(这是五年或更长时间前),当大小为 8 或更少时,二进制搜索总体上更快。 8 之后,字典开始领先,并且在 15 时变得更快。这是一百万次搜索的平均时间,包括对不在集合中的事物的一定百分比的搜索。我的结论是字典开销(计算哈希码和查找存储桶)大约等于二分搜索循环 3 或 4 次迭代的成本。
【解决方案2】:

没有人说过 为什么 字典是 O(1) 并且 为什么 它比二分查找快。一方面是字典不按键排序。字典的重点是转到键值引用的项目的准确*(出于所有实际目的)位置。它不会“搜索”该项目 - 它知道您想要的项目的确切位置。

所以对字典进行二分搜索是没有意义的,因为当集合已经知道某个项目的确切位置时,就不需要“搜索”它。

*这在哈希冲突的情况下并不完全正确,但是字典的原理是直接获取项目,任何额外的查找都是一个实现细节,应该很少见。

另一方面,据我了解,SortedListSortedDictionary 仅应在我需要插入/删除数据时使用。

当您希望在添加或删除数据时自动对数据进行排序时,应该使用它们。请注意,SortedDictionary 失去了“普通”字典的性能增益,因为它现在必须使用键值搜索位置。它的主要用途是允许您按顺序迭代键。

如果您对每个项目都有一个唯一的键值,不需要以任何特定的顺序迭代项目,并且想要最快的“获取”性能,那么Dictionary 就是要走的路。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 2020-11-05
    • 2016-04-16
    相关资源
    最近更新 更多