Lecture 017

Red-Black Tree

datatype 'a dict = Empty
                 | Red of 'a dict * 'a entry * 'a dict
                 | Black of 'a dict * 'a entry * 'a dict

functor

functor RBT (K: ORDERED) :> DICT where type Key.t = K.t
  = struct
      structure Key = K
      type 'a entry = Key.t * 'a
      val empty = Empty
      fun insert...
      fun loopup...
    end

structure StringDict = RBT(StringLt)
val r1 = StringDIct.insert(StringDict.empty, ("A", 1))

- r1;
val r1 - -: int stringDict.dict

invariant

  1. Sorting: tree is sorted by key
  2. Red-Black Invariant: Children of red nodes are black
  3. Black Height Invariant: The number of black nodes on any path from the root to a leaf is equal (the black height is (black_root + non-nil-black-nodes))

Note: (root) and leaf(Empty) are black

Implement Rotation

(*restorLeft: 'a dict -> 'a dict
REQUIRES: d is RBT || (or d is black && left child is ARBT && right child RBT)
ENSURES: restoreLeft(d) == RBT
*)
fun restoreLeft (Black(ed(Red(T1, x, T2), y, T3), z, T4))
  = Red(Black(T1, x, T2), y, Black(T3, z, T4))
  | restoreLeft (Black(Red(T1, x, Red(T2, y, T3)), 2, T4))
  = Red(Black(T1, x, T2), y, Black(T3, z, T4))
  | restoreLeft d = d

Implement Insert

(*insert: 'a dict * 'a entry -> 'a dict
REQURIES: d is a RBT
ENSURES: insert(d ,e) is a RBT such that ... inserted

ins: 'a dict -> 'a dict
REQUIRES: d is a RBT
ENSURES: ins(d) is sorted, contain right element, has same black height as d
         ins(Black(t)) is a RBT
         ins(Red(t)) is a ARBT
*)
fun insert (d, e as (k, v))
  = let
      fun ins Empty = Red(Empty, e, Empty)
        | ins (Black(l, e' as (k', _), r)))
        = (case Key.compare(k, k') of
               Equal => Black(l, e, r)
             | LESS => restoreLeft (Black(ins l, e', r))
             | GREATER => restoreRight (Black(l, e', ins r))) (*here ins l might be ARBT before restore*)
        | ins (Red(l, e' as (k', _), r))
        = (case Key.compare(k, k') of
               Equal => Red(l, e, r)
             | LESS => Red(ins l, e', r) (*here ins l has to be RBT*)
             | GREATER => Red(l, e', ins r))
in
      (case ins d of
        | Red(t as (Red(_), _, _)) => Black t
        | Red(t as (_, _, Red(_)) => Black t
        | d' => d'
    end

insert: works because an ARBT with the root recolored Black is an RBT

Red-Black Theorem

In a RBT, depth <= 2 log_2 (|nodes|+1)

Rotations

restoreLeft

restoreLeft

restoreRight

restoreRight
(the right side of this image is wrong)

correct

correct

Almost-BlackRed

Definition

  1. Sorting
  2. !!! EXCEPT: red root may have one red child !!!
  3. Black Height

Table of Content