Jon*_*lap 26 haskell doubly-linked-list
是否有可能在Haskell中有一个双向链表,实现它们的理想解决方案是什么?我正在实现一个场景图,其中每个小部件都有一个父节点和一个子节点,并且在图形中向上和向下查看都是有益的.
dfl*_*str 40
在Haskell中使用双向链表是不切实际的,因为你必须一次构建它.
例如,假设您有一个[1, 2, 3, 4, 5]要双重链接的列表.现在,让我们想象一下如何表示列表:
data DoubleList a
= LeftEnd a (DoubleList a)
| Middle a (DoubleList a) (DoubleList a)
| RightEnd a (DoubleList a)
Run Code Online (Sandbox Code Playgroud)
(为简单起见,我为两端使用了两个不同的构造函数)
要构建上面的列表,您必须首先构造第一个元素:
let e1 = LeftEnd 1 ...
Run Code Online (Sandbox Code Playgroud)
但是要构造第一个元素,您需要拥有第二个元素:
let e1 = LeftEnd 1 e2
e2 = Middle 2 e1 ...
Run Code Online (Sandbox Code Playgroud)
对于第二个元素,您需要第三个元素,等等:
let e1 = LeftEnd 1 e2
e2 = Middle 2 e1 e3
e3 = Middle 3 e2 e4
e4 = Middle 4 e3 e5
e5 = RightEnd 5 e4
Run Code Online (Sandbox Code Playgroud)
由于懒惰的评估,这在Haskell中可以做到; 这种策略被称为"打结"(你不必将它全部放在一个let块中;你可以把结构分成函数)
但是,换句话说,要创建一个双向链表,你需要一次构建它,如果你想改变它的任何部分,你需要使用Zipper或者只需要制作一个完整的副本每次.
我建议改为使用Data.Sequence,这是一种基于手指树的优化顺序存储实现.它支持非常快速的插入,删除和迭代,同时仍然是纯粹的功能数据结构.
否则,您可能只想使用Zippers,但将它们用于树而不是列表.有关Zippers的更多信息可以在Haskell Wiki上找到.拉链在这种情况下非常适合,因为它们提供了您所追求的确切功能:如果您访问带有拉链的树,您可以访问您正在访问的树部分的"父母",但树本身不必包含父引用.
| 归档时间: |
|
| 查看次数: |
6418 次 |
| 最近记录: |