红黑树包含太多的黑色节点和太少的红色节点

知道不多

这是我在这里提出的进一步问题

用F#编写Red Black Tree困难

根据先前的输入,我创建了该程序。

open System;

type Color = | R | B 

type tree = 
    | Node of int * Color * tree * tree
    | Leaf

let blackHeight tree = 
    let rec innerBlackHeight accm = function
        | Leaf -> accm + 1
        | Node(_, B, l, r) -> List.max [(innerBlackHeight (accm + 1) l); (innerBlackHeight (accm + 1) r)]
        | Node(_, R, l, r) -> List.max [(innerBlackHeight accm l); (innerBlackHeight accm r)]        
    innerBlackHeight 0 tree    

let isTreeBalanced tree = 
    let rec isBlackHeightSame = function
        | Node(n, c, l, r) -> 
            if (blackHeight l) = (blackHeight r) then 
                true && (isBlackHeightSame l) && (isBlackHeightSame r)
            else 
                false
        | Leaf -> true
    let isRootBlack = function
        | Node(n, c, _, _) -> 
            if c = B then 
                true 
            else 
                false
        | _ -> false
    let rec twoConsequtiveReds = function
        | Leaf -> true
        | Node(_, R, Node(_, R, _, _), _) -> false
        | Node(_, R, _, Node(_, R, _, _)) -> false
        | Node(_, _, l, r) -> (twoConsequtiveReds l) && (twoConsequtiveReds r)

    ((isBlackHeightSame tree) && (isRootBlack tree) && (twoConsequtiveReds tree))

let balance  = function 
    | Node (gpn, B, Node(pn, R, Node(cn, R, a, b), c), d) -> Node(pn, R, Node(cn, B, a, b), Node(gpn, B, c, d))
    | Node (gpn, B, a, Node(pn, R, b, Node(cn, R, c, d))) -> Node(pn, R, Node(gpn, B, a, b), Node(cn, B, c, d))
    | Node (gpn, B, Node(pn, R, a, Node(cn, R, b, c)), d) -> Node(cn, R, Node(pn, B, a, b), Node(gpn, B, c, d))
    | Node (gpn, B, a, Node(pn, R, Node(cn, R, b, c), d)) -> Node(cn, R, Node(gpn, B, a, b), Node(pn, B, c, d))    
    | Node (n, c, l, r) -> Node(n, c, l, r)
    | _ -> failwith "unknown pattern"

let rec insert x tree = 
    let rec insertInner = function
        | Node(n, c, l, r) when x < n -> balance (Node(n, c, insertInner l, r))
        | Node(n, c, l, r) when x > n -> balance (Node(n, c, l, insertInner r))
        | Node(n, c, l, r) as node when x = n -> node
        | Leaf -> Node(x, R, Leaf, Leaf)
        | _ -> failwith "unknown pattern"
    match (insertInner tree) with
    | Node(n, _, l, r) -> Node(n, B, l, r)
    | t -> t

let rec findLowest = function
    | Node(n, _, Leaf, _) -> n
    | Node(_, _, l, _) -> findLowest l
    | _ -> failwith "Unknown pattern"

let rec countNodes = function
    | Node(_, c, l, r) -> 
        let (x1, y1, z1) = countNodes l
        let (x2, y2, z2) = countNodes r
        if c = B then
            (1 + x1 + x2, y1 + y2, z1 + z2)
        else
            (x1 + x2, 1 + y1 + y2, z1 + z2)
    | Leaf -> (0, 0, 1)

let rec delete x tree = 
    let rec innerDelete = function
        | Node(n, c, l, r) when x < n -> balance (Node(n, c, innerDelete l, r))
        | Node(n, c, l, r) when x > n -> balance (Node(n, c, l, innerDelete r))
        | Node(n, c, Leaf, Leaf) when x = n -> Leaf
        | Node(n, c, l, Leaf) when x = n -> balance l
        | Node(n, c, Leaf, r) when x = n -> balance r
        | Node(n, c, l, r) when x = n ->  balance (Node((findLowest r), c, l, r))
        | _ -> failwith "unexpected pattern"
    match (innerDelete tree) with
    | Node(n, _, l, r) -> Node(n, B, l, r)
    | t -> t

let generateNums n = 
    seq {for i in 0 .. n - 1 -> i}

[<EntryPoint>]
let main args = 
    let mutable tree = Leaf
    for i in generateNums 100000 do 
        tree <-insert i tree    
    printfn "%A" tree
    printfn "%i" (blackHeight tree)
    printfn "%b" (isTreeBalanced tree)
    let (bc, rc, lc) = countNodes tree
    printfn "black nodes %i red nodes %i leaf nodes %i" bc rc lc
    0

我面临的问题是

  1. 对于0到99999的树,它将生成具有99994个黑色节点,6个红色节点和100001个叶子节点的树。

这正常吗?那棵树有这么少的红色节点?

我已经编写了一个函数来根据3条规则验证树是否有效(根始终为黑色,所有分支的黑色高度均相同,红色节点没有红色子节点),并且我的方法说生成的树确实是有效的。

  1. 黑色节点过多的问题在于某些分支充满了黑色节点,如果我尝试删除一个节点,则旋转无助于平衡树,该分支的黑色高度始终小于另一个树的分支。

所以我的问题是...一棵红黑树的红色结点太少是正常的吗?在这种情况下,如何在删除时使树保持平衡?

内斯

没有“黑色节点太多”之类的东西。完全没有红色节点意味着树是最平衡的。将新的红色节点引入全黑树会增加其不平衡(首先)。

删除全黑树中的黑节点时,请遵循删除算法,以确保保留属性。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

红黑树包含太多的黑色节点和太少的红色节点

来自分类Dev

更新红黑树中的节点

来自分类Dev

为什么在红黑树插入操作中新插入的节点总是被涂成红色?

来自分类Dev

左侧倾斜的红黑树计划中红色节点的预期百分比?

来自分类Dev

从全黑的红黑树中删除节点

来自分类Dev

是否可以在不删除和插入的情况下更新红黑树中的节点密钥?

来自分类Dev

红黑树中插入的节点着色错误

来自分类Dev

通过将每个节点的“父节点”存储在红黑树中可以简化哪些操作?

来自分类Dev

Avl树和红黑树的比较

来自分类Dev

Rust中的红黑树,获得“预期的结构节点,找到了可变引用”

来自分类Dev

BST的红黑树和高度属性

来自分类Dev

为什么红黑树总是将零个节点作为叶节点,这意味着什么?

来自分类Dev

红黑树的直觉

来自分类Dev

红黑搜索树

来自分类Dev

红黑树与安德森树

来自分类Dev

红黑树:卡尔版本

来自分类Dev

红黑树平衡了吗

来自分类Dev

红黑树高度证明

来自分类Dev

红黑树无效转换

来自分类Dev

在红黑树中,插入和删除如何比AVL树更快?

来自分类Dev

在一棵红黑树的旋转

来自分类Dev

缓慢的Python红黑树性能

来自分类Dev

为minDiff增强红黑树

来自分类Dev

红黑树Java中的空子

来自分类Dev

红黑树-打印错误

来自分类Dev

Tarjan自上而下的红黑树效率

来自分类Dev

值的红黑树插入操作的行为

来自分类Dev

红黑树中的 insert_rebalance

来自分类Dev

红黑树-K插入和K删除所需的最大旋转次数?