Haskell 函数式编程中最简单的自平衡树是什么?

Haskell 函数式编程中最简单的自平衡树是什么?,haskell,functional-programming,tree,tree-balancing,Haskell,Functional Programming,Tree,Tree Balancing,我在Haskell设计一个自平衡树。作为一种锻炼,因为它是很好的有在你的手 以前在C和Python中,我更喜欢Treaps和Splay树,因为它们有简单的平衡规则。我一直不喜欢R/B树,因为它们看起来比它们的价值还大 现在,由于Haskell的功能性质,事情似乎发生了变化。我可以用10行代码编写一个R/B插入函数。另一方面,Treaps需要包装来存储随机数生成器,而Splay树则需要自上而下的方式 所以我问你是否有其他类型树木的经验? 哪些树更善于利用函数式语言的模式匹配和自上而下的特性?正如您

我在Haskell设计一个自平衡树。作为一种锻炼,因为它是很好的有在你的手

以前在C和Python中,我更喜欢Treaps和Splay树,因为它们有简单的平衡规则。我一直不喜欢R/B树,因为它们看起来比它们的价值还大

现在,由于Haskell的功能性质,事情似乎发生了变化。我可以用10行代码编写一个R/B插入函数。另一方面,Treaps需要包装来存储随机数生成器,而Splay树则需要自上而下的方式

所以我问你是否有其他类型树木的经验?
哪些树更善于利用函数式语言的模式匹配和自上而下的特性?

正如您所说的,红黑树并不难使用。你给我钱了吗?您可能有兴趣使用类似于另一棵树的东西来扩充您的基础数据结构,您可能会发现有趣的是它是红黑树的简化。

它是已经实现的树


Haskell中有一些很好的平衡树实现,比如Data.Map和Data.Set。他们不能满足你的需要吗?不要重新实现,重新使用。

OCaml标准库使用AVL树作为其
映射
函子。如果包含
remove
操作,似乎比RB树更容易实现。

好的,我想回答这个问题没有太多的参考或研究。相反,我花时间尝试你不同的想法和树。我没有发现比RB树更好的东西,但也许这只是搜索偏差

RB树可以通过四个简单的规则(插入)进行平衡,如下所示:

AVL树可以以类似的模式匹配方式进行平衡。但是,规则也不会压缩:

balance T (T (T a x b   dx) y c (-1)) z d (-2) = T (T a x b dx) y (T c z d  0) 0
balance T a x (T b y (T c z d   dz)   1 )   2  = T (T a x b  0) y (T c z d dz) 0
balance T (T a x (T b y c   1 )   1 ) z d (-2) = T (T a x b -1) y (T c z d  0) 0
balance T (T a x (T b y c (-1))   1 ) z d (-2) = T (T a x b  0) y (T c z d  1) 0
balance T (T a x (T b y c   _ )   1 ) z d (-2) = T (T a x b  0) y (T c z d  0) 0
balance T a x (T (T b y c   1 ) z d (-1))   2  = T (T a x b -1) y (T c z d  0) 0
balance T a x (T (T b y c (-1)) z d (-1))   2  = T (T a x b  0) y (T c z d  1) 0
balance T a x (T (T b y c   _ ) z d (-1))   2  = T (T a x b  0) y (T c z d  0) 0
balance t = t
由于AVL树通常被认为不如RB树,它们可能不值得额外的麻烦

理论上,AA树可以通过以下方式轻松平衡:

balance T n (T n a x b) y c = T n a x (T n b y c) -- skew
balance T n a x (T n b y (T n c z d)) = T (n+1) (T n a x b) y (T n c z d) --split
balance T n a x b = T n a x b
但不幸的是,Haskell不喜欢
n
的重载。AA树的一个不太标准的实现(不使用秩,而是更类似于R和B)可能会很好地工作

Splay树很困难,因为您需要关注单个节点,而不是树的静态结构。这可以通过以下方式完成


Treaps在功能环境中也很难实现,因为您没有全局随机生成器,但需要在每个节点中保留实例。这可以通过解决,但即使这样,您也不能使用模式匹配进行优先级比较。

这不是一个直接的答案,但可以阅读“纯功能数据结构”来获得一些好的想法。我喜欢它。它不涉及详细的结构,但提供了一个很好的总体观点。您需要一个搜索树,还是序列的树表示(如fingertrees-带有连接和拆分)?在后一种情况下,纯功能的2-3棵树是微不足道的。手指树看起来真的很酷。我很高兴你让我发现了这个数据结构。然而,它们看起来并不是特别容易实现。我见过的大多数实现都使用2-3树,并在许多用例中概括了该树。你可能对AA树感兴趣,它们只是简化的红黑树。谢谢你给我指出AA树,我喜欢它们!不幸的是,它们对秩的使用不能很好地用于模式匹配:(出于算法目的,经常会出现这样的情况,即需要一棵树,在每个节点中存储特定的信息。无论是统计树中子树的大小,还是区间树中最右边的点。
balance T n (T n a x b) y c = T n a x (T n b y c) -- skew
balance T n a x (T n b y (T n c z d)) = T (n+1) (T n a x b) y (T n c z d) --split
balance T n a x b = T n a x b