好的,我猜回答这个问题并没有很多参考资料或研究。相反,我花时间尝试了您提出的不同想法和树。我没有找到比红黑树更好的东西,但也许这只是搜索偏见。
红黑树可以通过四条简单的规则(如
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树可以通过类似模式匹配的方式实现平衡。然而,规则不会像之前那样压缩得那么好:
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树似乎普遍被认为不如红黑树,它们可能不值得额外的麻烦。
AA树理论上可以通过以下方式很好地平衡:
balance T n (T n a x b) y c = T n a x (T n b y c)
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)
balance T n a x b = T n a x b
但不幸的是,Haskell 不喜欢 n
的重载。可能一个使用类似 R 和 B 的更少标准化实现 AA 树会很好。
Splay 树很困难,因为你需要专注于单个节点,而不是树的静态结构。可以通过 合并插入和 splay 来完成。
在函数环境中,Treap 也很难做到,因为你没有全局的随机生成器,但需要在每个节点中保留实例。这可以通过 将生成优先级的任务留给客户端 来解决,但即使这样,你也不能使用模式匹配进行优先级比较。