Ответ 1
Хорошо, я думаю, не было много ссылок или исследований для ответа на этот вопрос. Вместо этого я потратил время, чтобы попробовать ваши разные идеи и деревья. Я не нашел ничего лучше, чем деревья RB, но, возможно, это просто искажение поиска.
Дерево RB может быть (вставка) сбалансировано с четырьмя простыми правилами, так как показано Крисом Окасаки:
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 швы обычно считаются уступающими деревьям 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
. Возможно, что менее стандартная реализация деревьев АА, а не использование рангов, а что-то более похожее на R и B, будет работать хорошо.
Деревья Splay трудны, потому что вам нужно сосредоточиться на одном node, а не на статической структуре дерева. Это можно сделать с помощью слияния вставки и воспроизведения.
Treaps также непросто делать в функциональной среде, так как у вас нет глобального генератора случайных чисел, но нужно сохранять экземпляры в каждом node. Это можно решить, оставляя задачу генерации приоритетов для клиента, но даже тогда вы не можете выполнить приоритетное сравнение с использованием сопоставления шаблонов.