什么是Zipper数据结构,我应该使用它吗?

时间:2008-12-19 09:05:14

标签: data-structures functional-programming theory zipper

问题很简单:我无法理解Zipper数据结构。

我的问题与它在树上的用途有关。

我想了解如何使用zipper更改树节点。如何不复制整棵树(或大部分树)。

请澄清拉链是否错误。也许它无法帮助树更新?
或者,也许,有可能更新树,我只是看不到路?

4 个答案:

答案 0 :(得分:51)

让我们从列表的Zipper-analog开始。如果您想修改列表的第n个元素,则需要O(n),因为您必须复制n-1个第一个元素。相反,您可以将列表保持为结构((第一个n-1个元素反转)第n个元素(其余元素))。例如,可修改为3的列表(1 2 3 4 5 6)将表示为((2 1) 3 (4 5 6))。现在,您可以轻松地将3更改为其他内容。您也可以轻松地将焦点向左移动((1) 2 (3 4 5 6))和向右((3 2 1) 4 (5 6))

拉链与树木相同。你在树中加上一个焦点加上一个上下文(直到父母,直到孩子),它以一种形式为你提供整个树,它可以在焦点上轻松修改,并且很容易上下移动焦点。

答案 1 :(得分:12)

这是一篇非常好的文章,解释using the zipper for a tiling window manager in Haskell。维基百科的文章不是一个很好的参考。

简而言之,拉链是树或列表结构中特定节点的指针或句柄。拉链提供了一种自然的方式来获取树结构并对其进行处理,就像树被聚焦节点“拾取”一样 - 实际上,您获得第二棵树而不需要由原始树构成的额外副本或影响其他用户树。

给出的示例显示了如何使窗口最初按位置排序,然后使用指向焦点窗口的拉链来建模焦点。您可以获得一组很好的O(1)操作,例如插入和删除操作,而无需特殊情况下的焦点窗口或编写其他代码。

答案 2 :(得分:5)

了解你Haskell也有a great chapter about zippers

答案 3 :(得分:2)

This article与Haskell有关,但它也很好地解释了拉链,并且很容易从Haskell特定的内容中抽象出来。