简体   繁体   English

自平衡树在功能编程中最简单的是什么?

[英]What Self Balancing Tree is simplest in Functional Programming?

I'm designing a self balancing tree in Haskell. 我正在Haskell中设计一个自平衡树。 As an exercise and because it is nice to have in your back hand. 作为一项练习,因为你的后背很好。

Previously in C and Python I preferred Treaps and Splay Trees due to their simple balancing rules. 之前在C和Python中,由于其简单的平衡规则,我更喜欢Treaps和Splay Trees。 I always disliked R/B Trees, since they seemed like more work than they were worth. 我总是不喜欢R / B树,因为它们似乎比它们的价值更多的工作。

Now, due to the functional nature of Haskell, things seem to have changed. 现在,由于Haskell的功能性,事情似乎发生了变化。 I can write a R/B insert function in 10 lines of code. 我可以用10行代码编写一个R / B插入函数。 Treaps on the other hand requires wrapping to store the random number generator, and Splay Trees are a pain to do top-down. 另一方面,Treaps需要包装以存储随机数生成器,并且Splay Trees是自上而下的痛苦。

So I'm asking if you have experience with other types of trees? 所以我问你是否有其他类型树木的经验? Which ones are better at utilizing the pattern matching and top-down nature of functional languages? 哪些更好地利用函数式语言的模式匹配和自上而下的性质?

Ok, I guess there wasn't a lot of references or research for answering this question. 好吧,我想没有很多参考或研究来回答这个问题。 Instead I've taken the time to try your different ideas and trees. 相反,我花时间尝试你的不同想法和树木。 I didn't find anything a lot better than RB trees, but perhaps that's just search bias. 我没有找到比RB树更好的东西,但也许这只是搜索偏差。

The RB tree can be (insertion) balanced with four simple rules, as shown by Chris Okasaki : RB树可以(插入)平衡四个简单的规则,如Chris Okasaki所示

balance T (T R (T R a x b) y c) z d = T R (T B a x b) y (T B c z d)
balance T (T R a x (T R b y c)) z d = T R (T B a x b) y (T B c z d)
balance T a x (T R b y (T R c z d)) = T R (T B a x b) y (T B c z d)
balance T a x (T R (T R b y c) z d) = T R (T B a x b) y (T B c z d)
balance T a x b = T B a x b

AVL trees can be balanced in a similar pattern matching way. AVL树可以以类似的模式匹配方式进行平衡。 However the rules don't compress as well: 但是规则也不会压缩:

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

As AVL trees seams to generally be considered inferior to RB trees, they are probably not worth the extra hassle. 由于AVL树木接缝通常被认为不如RB树,它们可能不值得额外的麻烦。

AA trees could theoretically be balanced nice and easily by: 从理论上讲,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

But unfortunately Haskell don't like the overloading of n . 但不幸的是Haskell不喜欢n的超载。 It is possible that a less standard implementation of AA trees, not using ranks, but something more similar to R and B, would work well. AA树的不太标准的实现,不使用等级,但更类似于R和B,可能会很好。

Splay trees are difficult because you need to focus on a single node, rather than the static structure of the tree. Splay树很难,因为您需要关注单个节点,而不是树的静态结构。 It can be done by merging insert and splay . 它可以通过合并插入和展开来完成。

Treaps are also uneasy to do in a functional environment, as you don't have a global random generator, but need to keep instances in every node. Treaps在功能环境中也很难做,因为您没有全局随机生成器,但需要在每个节点中保留实例。 This can be tackled by leaving the task of generating priorities to the client , but even then, you can't do priority comparison using pattern matching. 这可以通过将生成优先级的任务留给客户端来解决,但即使这样,您也无法使用模式匹配进行优先级比较。

As you say Red Black trees aren't that hard to use. 正如你所说,红黑树并不难以使用。 Have you given finger trees a look ? 看过手指树了吗? You might be interested in augmenting your base data structure with something like a zipper. 您可能有兴趣使用类似拉链的方式扩充基础数据结构 Another tree you might find interesting is the AA tree it is a simplification of Red Black Trees. 你可能会觉得有趣的另一棵树是AA树,它是红黑树的简化。

It's the one that's already implemented. 这是已经实施的那个。

There are fine implementations in Haskell of balanced trees such as Data.Map and Data.Set. 在平衡树的Haskell中有很好的实现,例如Data.Map和Data.Set。 Don't they fulfill your needs? 他们不满足你的需求吗? Don't reimplement, reuse. 不要重新实现,重用。

The OCaml standard library uses an AVL tree for its map functor. OCaml标准库使用AVL树作为其map仿函数。 It seems as though it's easier to implement than an RB-tree if you include a remove operation. 如果包含remove操作,似乎比RB树更容易实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 函数式编程中的代数结构是什么? - What are algebraic structures in functional programming? 纯函数式编程中的“价值”是什么? - What is “value” in pure functional programming? 这种函数式编程优化叫什么? - What is this functional programming optimization called? 允许相等值位于自平衡二叉树两侧的缺点? - Disadvantages of allowing equal values to be on either side of a self balancing binary tree? 函数式编程:如何处理函数式编程中的异常或其等价物 - Functional Programming: How to handle exceptions in Functional Programming or what is its equivalent “世界”在函数式编程世界中意味着什么? - What does the “world” mean in functional programming world? 函数式编程中的“部分函数”到底是什么意思? - What exactly is meant by “partial function” in functional programming? OOAD是OOP的功能编程的等价物是什么? - As OOAD is to OOP what is the equivalent for functional programming? 功能编程:Curry&Fold - 什么是词源? - Functional programming: Curry & Fold - what are the etymologies? 哪些语言实现了功能编程的功能? - What languages implement features from functional programming?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM