Java 持久哈希表实现
在我正在开发的一个程序中,我开发了一个大型的“线程树”(每个节点最多有k个子节点),其中每个线程对从其父节点继承的哈希表进行一些修改。有没有一种方法可以实现某种程度上是“持久的”(在某种意义上)的哈希表 也就是说,是否有一种方法可以实现一个键值对,其中至少有O(logn)个查找、插入和删除是完全持久的,但与普通哈希表一样“节省空间”(最坏情况)?“与普通哈希表一样节省空间”是一个相当模糊的规范,因为“普通”可能表示链接或探测,具体取决于您询问的对象。我认为还没有人设计出易于理解的持久哈希表 要获得具有所需复杂性的持久性键值映射,最简单的方法是使用持久性二进制搜索树。查找是来自短暂(非持久)BST的常见算法。但是,插入更改,并变成类似(伪Java)的内容:Java 持久哈希表实现,java,c++,data-structures,hashtable,persistent,Java,C++,Data Structures,Hashtable,Persistent,在我正在开发的一个程序中,我开发了一个大型的“线程树”(每个节点最多有k个子节点),其中每个线程对从其父节点继承的哈希表进行一些修改。有没有一种方法可以实现某种程度上是“持久的”(在某种意义上)的哈希表 也就是说,是否有一种方法可以实现一个键值对,其中至少有O(logn)个查找、插入和删除是完全持久的,但与普通哈希表一样“节省空间”(最坏情况)?“与普通哈希表一样节省空间”是一个相当模糊的规范,因为“普通”可能表示链接或探测,具体取决于您询问的对象。我认为还没有人设计出易于理解的持久哈希表 要获
//如果k的值已经在树中,则覆盖该值
节点插入(节点,键k,值v)
{
if(knode.key)
返回新节点(Node.key、Node.val、Node.left、insert(Node.right、k、v));
其他的
返回新节点(k,v,Node.left,Node.right);
}
请注意,insert例程返回一个新的树,这可能看起来效率低下,但它只更改它所遍历的节点。这是平均的O(lgn),所以它平均分配O(lgn)。这是一个非常节省空间的系统
要获得最坏情况下的O(lgn)行为,请使用红黑树。另请参阅有关函数式编程中数据结构的文献,例如Okasaki的著作。Clojure实现了一整套持久数据结构,如哈希映射。它是开源的,所以也许你应该看看 也就是说,是否有一种方法可以实现一个键值配对,其中至少有O(logn)个查找、插入和删除是完全持久的,但与普通哈希表一样“节省空间”(最坏情况) 对。Driscoll等人的第5节展示了一种技术,该技术可以使插入、删除和查找具有O(lgn)时间和O(1)空间复杂性的完全持久的红黑树 它们的数据结构不是融合持久的。有关持久性的更多信息,请参阅 有没有一种方法可以实现一个键值配对,其中至少有O(logn)个查找、插入和删除是完全持久的,但与普通哈希表一样“节省空间”(最坏情况) 确实有。很多方面 例如,在Haskell中,简单的、大小平衡的二叉树(或有界平衡的树),如下所述:
- 斯蒂芬·亚当斯,“有效集:平衡行为”,《函数编程杂志》3(4):553-562,1993年10月
- J.Nievergelt和E.M.Reingold,“有界平衡的二元搜索树”,暹罗计算杂志2(1),1973年3月
insert :: Ord k => k -> a -> Map k a -> Map k a -- O(log n)
lookup :: Ord k => k -> Map k a -> Maybe a -- O(log n)
delete :: Ord k => k -> Map k a -> Map k a -- O(log n)
在完全坚持的同时。空间使用为O(n)
要获得更好的常数因子,请尝试使用具有相同总体复杂性的数据结构
替代结构包括:
- 由于密钥存储密集,持久性尝试比哈希表提高了空间使用率
insert :: Ord k => k -> a -> Map k a -> Map k a -- O(log n)
lookup :: Ord k => k -> Map k a -> Maybe a -- O(log n)
delete :: Ord k => k -> Map k a -> Map k a -- O(log n)