【问题标题】:Can I represent a Red-black tree as binary leaf tree?我可以将红黑树表示为二叉叶树吗?
【发布时间】:2011-09-08 10:37:24
【问题描述】:

我一直在使用 Haskell 中的 RB 树实现,但很难对其进行一些更改,因此数据只放在叶子中,就像在二叉叶树中一样:

    /+\
   /   \
 /+\    \
/   \    c
a   b

内部节点将保存其他信息,例如树的大小,除了节点的颜色(就像在普通的 RB 树中一样,但数据只保存在叶子中)。我也不需要对插入的数据进行排序。我在插入数据时仅使用 RB 来获得平衡树,但我想保持插入数据的顺序。

原始代码是(来自冈崎书):

data Color = R | B
data Tree a = E | T Color (Tree a ) a (Tree a)

insert :: Ord a => a -> Tree a -> Tree a
insert x s = makeBlack (ins s)
    where ins E = T R E x E
        ins (T color a y b) 
            | x < y = balance color (ins a) y b
            | x == y = T color a y b
            | x > y = balance color a y (ins b)
        makeBlack (T _ a y b) = T B a y b

我将其更改为:(导致 Exception:Non-exhaustive patterns in function ins)

data Color = R | B deriving Show
data Tree a = E | Leaf a | T Color Int (Tree a) (Tree a)

insert :: Ord a => a -> Set a -> Set a
insert x s = makeBlack (ins s)
    where 
        ins E = T R 1 (Leaf x) E
        ins (T _ 1 a E) = T R 2 (Leaf x) a
        ins (T color y a b)
            | 0 < y = balance color y (ins a) b
            | 0 == y = T color y a b
            | 0 > y = balance color y a (ins b)
        makeBlack (T _ y a b) = T B y a b

原来的平衡函数是:

balance B (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 B (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 B 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 B 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 color a x b = T color a x b

从上面的代码中可以明显看出,我做了一些改动。

提前感谢您的帮助:)

编辑:对于我正在寻找的表示形式,Chris Okasaki 建议我使用二进制随机访问列表,如他的书中所述。另一种方法是简单地调整 Data.Set 中的代码,它被实现为权重平衡树。

【问题讨论】:

  • 你不会给已经存在的叶节点E添加一个a元素参数吗?
  • E 代表一棵空树,或者如果在节点中使用,例如T Color (Leaf 2) E,表示节点有左叶但没有右叶。也许我代表的方式不对?谢谢
  • 你为什么要使用树?如果你只想保持插入顺序,普通列表可能是最好的选择。
  • 目的是使用树来替代列表的表示形式。这样,搜索和排序操作可以并行完成,例如使用不同的处理器处理树的每一侧。这只是一个比较性能的实验。
  • 重新平衡可能会移动其他叶子。所以我认为这并不容易......

标签: algorithm haskell red-black-tree


【解决方案1】:

假设您的意思是insert :: a -&gt; Tree a -&gt; Tree a,那么您的错误可能源于没有ins (Leaf a) 的子句。

【讨论】:

  • 这是一个不变量。不会有一片叶子单独站立的情况。它必须在树节点(T)中。省略叶子不会给出非详尽的例外。但是我的问题在于其他模式,我确信这些模式不是很好,也不太确定该怎么做。
  • Leaf 节点可能总是由 T 构造函数保护,但您在最后一个子句中递归到 T 构造函数。所以ins 最终必须知道如何处理Leaf 节点。添加一个像ins (Leaf x) = error "dmwit told you so" 这样的子句,然后自己看看。
猜你喜欢
  • 2017-07-24
  • 2012-11-22
  • 2019-02-25
  • 2018-06-30
  • 1970-01-01
  • 2018-09-17
  • 1970-01-01
  • 1970-01-01
  • 2016-03-18
相关资源
最近更新 更多