【问题标题】:What is the Zipper data structure and should I be using it?什么是 Zipper 数据结构,我应该使用它吗?
【发布时间】:2010-09-27 16:24:02
【问题描述】:

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

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

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

如果我对拉链有误,请澄清一下。也许它无法帮助更新树?
或者,也许可以更新树而我只是看不到路?

【问题讨论】:

  • 我不知道,但那篇维基百科文章完全无法理解。因此混乱

标签: data-structures functional-programming theory zipper


【解决方案1】:

让我们从列表的拉链模拟开始。如果您想修改列表的第 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)) 移动。

拉链与应用于树木的想法相同。您代表树中的某个焦点加上一个上下文(上至父级,下至子级),它以一种形式为您提供整个树,它可以在焦点处轻松修改,并且可以轻松上下移动焦点。

【讨论】:

  • 我的意思是,它阐明了“拉链”结构,但没有阐明更新方法。
  • 等等,我怎样才能反转树??
  • 嗯,对于树木,它并没有完全颠倒过来。拉链专注于树的某个节点,由该节点的子节点和该节点的上下文(带有孔而不是节点的树)组成。见haskell.org/haskellwiki/Zipper
  • @namin: 一个问题:为什么我们需要反转第一个n-1 元素?我完全不知道有什么目的。请解释一下。
  • @eSKay:深思熟虑的问题。如果获取列表中的任何元素需要恒定的时间,您就不需要这样做。但通常情况下,列表具有头部和其余部分的原始访问器,因此反转前 n-1 个元素的基本原理很清楚:您很快想要获取前一个元素,这样它就是头部。
【解决方案2】:

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

简而言之,拉链是指向树或列表结构中特定节点的指针或句柄。拉链提供了一种自然的方式来获取树结构并将其视为树被聚焦节点“拾取” - 实际上,您获得第二棵树而无需从原始树制作额外副本或影响其他用户树。

给出的示例显示了如何使窗口最初按屏幕上的位置排序,然后使用指向焦点窗口的拉链来模拟焦点。您可以获得一组不错的 O(1) 操作,例如插入和删除,而无需对焦点窗口进行特殊处理或编写额外的代码。

【讨论】:

【解决方案3】:

Learn You a Haskell 也有 a great chapter about zippers

【讨论】:

    【解决方案4】:

    This article 与 Haskell 相关,但它也很好地解释了拉链,应该很容易从 Haskell 的细节中抽象出来。

    【讨论】:

      猜你喜欢
      • 2011-12-12
      • 2011-10-24
      • 1970-01-01
      • 2021-02-26
      • 2014-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多