【问题标题】:Verify a red black tree验证红黑树
【发布时间】:2018-10-10 18:19:33
【问题描述】:

我正在尝试验证二叉树是否是红黑树。 我需要检查的一些属性是:

  1. 根是黑色的
  2. 不能有 2 个连续的红色节点。
  3. 您需要添加空节点作为叶子节点,其颜色为黑色。
  4. 从叶子到根的每条路径都包含相同数量的黑色节点

不知何故,我的测试用例都通过了,但我确定我没有实现上面的数字 4。

如何检查从根到Empty(末尾)的任何深度是否具有相同数量的黑色节点?

我将我的树定义为:

type 'a tree = Empty | T of color * 'a tree * 'a * 'a tree 

我的代码只是将当前树与一些坏情况匹配并返回 false。否则,调用左右分支的递归函数。

let rec good_RB t = match t with
   | Empty -> true
   | T (R, T (R, _, _, _), _, _)
   | T (R , _, _, T (R, _, _, _)
     -> false
   | T (_, lft, _, rgt) -> good_RB lft && good_RB rgt

【问题讨论】:

  • 实际上第四个测试是:从叶子到根的每条路径都包含相同数量的黑色节点。
  • 我编辑了您的代码以添加 Empty 案例
  • @Lhooq 谢谢你的帮助。

标签: data-structures ocaml red-black-tree


【解决方案1】:

好吧,你需要保留一个柜台:

let rec nb_blacks_lftmst acc = function
  | Empty -> acc
  | T (c, lft, _, _) ->
    nb_blacks_lftmst (match c with R -> acc | B -> acc + 1) lft

let good_count = function
  | Empty -> true
  | T (_, lft, _, rgt) ->
    let cpt = nb_blacks_lftmst 0 lft in
    let rec aux acc = function
      | Empty -> acc = cpt
      | T (c, lft, _, rgt) ->
        let acc = match c with R -> acc | B -> acc + 1 in
        aux acc lft && aux acc rgt
    in
    aux 0 lft && aux 0 rgt

这样的事情应该可以工作。 (在我的回答中,最左边的路径被访问了两次,第一次是获取见证计数器,第二次是因为我不想写复杂的代码而不是第二次访问它)

【讨论】: