“与普通哈希表一样节省空间”是一个相当模糊的规范,因为“普通”可能意味着链接或探测,具体取决于您询问的对象。我认为还没有人设计过易于理解的持久哈希表。
获取具有所需复杂性的持久键值映射的最简单方法是使用持久二叉搜索树。查找是来自临时(非持久)BST 的熟悉算法。但是,插入更改,并变成类似(伪 Java)的东西:
// overwrites the value for k if it's already in the tree
Node insert(Node node, Key k, Value v)
{
if (k < node.key)
return new Node(node.key, node.val, insert(node.left, k, v), node.right);
else if (k > node.key)
return new Node(node.key, node.val, node.left, insert(node.right, k, v));
else
return new Node(k, v, node.left, node.right);
}
请注意,insert 例程返回一个新树,这似乎效率低下,但它只会更改它所遍历的那些节点。这是平均O(lg n),所以它平均进行O(lg n)分配。这与它所获得的一样节省空间。
要获得最坏情况的 O(lg n) 行为,请使用红黑树。另请参阅有关函数式编程中数据结构的文献,例如Okasaki的作品。