我已经阅读了一些有关以下数据结构的信息:
- Bagwell的理想哈希尝试
- Larson的动态哈希表
- 红黑树
- 帕特里夏树
...我敢肯定还有很多其他人。对于每个人都更适合的方式,或者为什么我会选择一个而不是另一个,我很少见。因此,以下是这些方面的一些问题:
- 重要的是要了解哪些功能词典数据结构?
- 这些方法的优缺点是什么?
- 什么时候使用更命令性的数据结构有意义?
数字2和3是最重要的数字。:-)
我已经阅读了一些有关以下数据结构的信息:
...我敢肯定还有很多其他人。对于每个人都更适合的方式,或者为什么我会选择一个而不是另一个,我很少见。因此,以下是这些方面的一些问题:
数字2和3是最重要的数字。:-)
Answers:
我无法真正回答第二个问题而不会迷失方向(可以用来比较这些结构的维度太多),但是对于第三个问题,答案非常简单。
在以下情况下,请使用命令式数据结构:(a)绝对没有别名,或者(b)您确实需要使用别名才能有效广播。
如果根本没有数据结构的别名,那么您就不会利用功能性数据结构是持久的这一事实。因此,没有理由支付其费用。此建议有两个警告。首先,您可能更喜欢功能数据结构的实现的简单性:对功能性红黑树执行删除将使您受到诅咒,但是在具有父指针的命令性红黑树中实现删除将使您打算自杀。其次,分配可能比使用gc'd语言所期望的要昂贵,因为写入可以使数据结构移出年轻一代。我们确实没有很好的缓存效果和gc理论,因此您别无选择,只能进行基准测试。
其次,如果您需要广播频道,那么共享数据结构是一种很好的方法。使用恒定时间更新,您可以任意告诉其他许多人值已更改。(这就是为什么union-find是这么好的数据结构的原因。)使用纯粹的功能设置,您需要修改所有其他人员,或者为他们提供抽象的指针,使其成为您手动编码的状态(这有点钝)要做的事)。
如果您不希望使用别名和对象所有权,或者您需要同一数据结构的多个版本(例如,您需要新版本和旧版本),则只需使用功能数据结构即可。
我发现遵循该建议最困难的地方是图形算法。有很多非常优雅的命令式图算法,但是通常情况下(例如,在编写编译器时)您也需要持久性。人们通常尝试拆分差异并使用酷命令式算法,但尝试将版本控制附加到一边以获得持久性。这通常是非常可怕的,充满了错误,并且容易失去命令式算法的性能优势。
重要的是要了解哪些功能词典数据结构?
高度平衡的二叉树及其尝试是一个很好的全面折衷方案。也:
这些方法的优缺点是什么?
高度平衡的二叉树及其尝试是对原子密钥的全面妥协。序列键(例如字符串键)的尝试相同。
Patricia树可以快几倍,但只允许使用整数键。
哈希尝试可能比平衡二叉树快几倍,特别是如果哈希比比较便宜并且多态性有开销(例如.NET上的字符串)并且将指针写入堆的速度较快(例如,像JVM和CLR这样的虚拟机已经针对命令性语言而非功能性语言进行了优化)。哈希尝试还允许内部使用变异作为优化。
红黑树不那么重要,因为它们与高度平衡的树相比没有任何明显的好处,但是其显着的缺点是它们不允许有效的合并,交叉和区别。
同样,在实践中,手指树也不是更好。
什么时候使用更命令性的数据结构有意义?
当您的字典被填充一次,然后仅用于查找(即冻结)时。
当您需要性能时(像.NET这样的体面的哈希表Dictionary
通常比任何通用的纯功能字典快10-40倍)。
当您需要弱字典时,因为没有已知的纯功能弱字典。