Piros-fekete fák

Adatszerkezet

data Colour
	= R | B
		deriving (Eq, Show)

data T a
	= E 
	| N Colour (T a) a (T a)
		deriving (Eq, Show)

Invariánsok

Elvárjuk, hogy az algoritmusok megtartsák a következő tulajdonságokat (invariánsok):

  1. A fa rendezett (keresőfa).
  2. A piros csúcsoknak feketék a gyerekeik.
  3. Minden úton ugyanannyi fekete csúcs van.
  4. A gyökér fekete.

Ha 2. és 3. teljesül, akkor az utak hosszában az eltérés legfeljebb kétszeres lehet, így a fa nagyjából kiegyensúlyozott.

Beszúrás

ins :: Ord a => a -> T a -> T a
ins a t  =  blacken (f t) where 
	f (N c l b r)
		| a <  b =  n c (f l) b r
		| a == b =  n c l     a r
		| a >  b =  n c l     b (f r)
	f E          =  n R E     a E

blacken (N _ l a r) =  N B l a r

Az n korrigáló fa-készítés definíciója a következő dián látható.

Korrigáló fa-készítés

n :: Colour -> T a -> a -> T a -> T a
n B (N R (N R x a y) b z) c v = N R (N B x a y) b (N B z c v)
n B (N R x a (N R y b z)) c v = N R (N B x a y) b (N B z c v)
n B x a (N R (N R y b z) c v) = N R (N B x a y) b (N B z c v)
n B x a (N R y b (N R z c v)) = N R (N B x a y) b (N B z c v)
n c l a r                     = N c l a r

A kód magyarázatától itt most eltekintünk. (A tárgy célja elsősorban a papíron már előkészített algoritmusok implementálása funkcionális nyelven.)

Bejárás

Egyszerűbb definíció:

-- inorder :: T a -> [a]
-- inorder E = []
-- inorder (N _ l a r) = inorder l ++ [a] ++ inorder r

Hatékonyabb, gyűjtögető definíció (kiküszöböljük a (++) használatát):

inorder :: T a -> [a]
inorder t = f [] t  where
	-- f :: [a] -> T a -> [a]
	f acc E = acc
	f acc (N _ l a r) = f (a: f acc r) l

Rendezés piros-fekete fákkal

sort :: Ord a => [a] -> [a]
sort = inorder . foldr ins E

Készen vagyunk.

Test>