AVL fák

Bináris fa adatszerkezet

Tekintsük a következő adatszerkezetet (bináris fa):

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

Feladat: Egy elemű fa

Definiáljuk:

singleton :: a -> T a

Test>
N E 'x' E :: T Char

Feladat: V alakú fa

Definiáljuk:

cherry :: a -> a -> a -> T a

Test>
N (N E 'a' E) 'b' (N E 'c' E) :: T Char

Feladat: 7 elemű fa

Készítsünk egy 2 mélységű teljes fát készít 7 elemből!

seven :: [a] -> T a

Test>
N (N (N E 1 E) 2 (N E 3 E)) 4 (N (N E 5 E) 6 (N E 7 E)) :: T Integer

Feladat: Inorder bejárás

Definiáljuk:

inorder :: T a -> [a]

Test>
True :: Bool
Test>
True :: Bool

Feladat: Preorder bejárás

Definiáljuk:

preorder :: T a -> [a]

Test>
True :: Bool
Test>
True :: Bool

Feladat: Postorder bejárás

Definiáljuk:

postorder :: T a -> [a]

Test>
True :: Bool
Test>
True :: Bool

Keresőfák

Rendezett fa (kersőfa): Minden csúcsra a bal oldali elemek kisebbek mint a csúcselem, a jobb oldaliak meg nagyobbak.

Feladat: Rendezett-e a lista

Segédfeladat: Állapítsuk meg egy listáról hogy rendezett-e!

sortedList :: Ord a => [a] -> Bool
 -- and, zipWith, (<), tail

Test>
True :: Bool
Test>
True :: Bool

Feladat: Rendezett-e a fa

Állapítsuk meg egy fáról hogy rendezett-e!

sorted :: Ord a => T a -> Bool
 -- inorder, sortedList

Test>
True :: Bool
Test>
True :: Bool

Feladat: Elemvizsgálat keresőfára

Definiáljuk:

member :: Ord a => a -> T a{-sorted-} -> Bool
 -- mintaillesztés, esetszétválasztás, rekurzió

Test>
True :: Bool
Test>
True :: Bool
Test>
True :: Bool

Feladat: Beszúrás keresőfába

Definiáljuk:

ins :: Ord a => a -> T a{-sorted-} -> T a 
 -- mintaillesztés, esetszétválasztás, rekurzió

Test>
True :: Bool
Test>
True :: Bool
Test>
True :: Bool

Kiegyensúlyozott fák

Egy fa kiegyensúlyozott, ha bármely részfájára a bal és jobb oldali részfa magasságkülönbsége legfeljebb 1.

AVL fa: Kiegyensúlyozott keresőfa

Feladat: Fa magassága

Magasság: A leghosszabb út hossza a fában.

height :: T a -> Int 
 -- mintaillesztés, rekurzió, max, (+)

Test>
True :: Bool
Test>
True :: Bool

Feladat: Fa ferdesége

Ferdeség: A bal és jobboldali részfák magasságának különbsége.

skew :: T a -> Int  
 -- mintaillesztés, height, (-)

Test>
True :: Bool
Test>
True :: Bool

Feladat: Kiegyensúlyozott-e a fa

Kiegyensúlyozott fa: A ferdeség abszolút értéke <= 1, és minden részfája kigyensúlyozott.

balanced :: T a -> Bool
 -- mintaillesztés, rekurzió, skew, abs, (<=), (&&)

Test>
True :: Bool
Test>
True :: Bool
Test>
True :: Bool
Test>
True :: Bool

Forgatások

A forgatások segítségével kicsit elbillent fát lehet kiegyensúlyozni.

Feladat: Jobbra forgatás

rightRot :: T a -> T a
 -- mintaillesztés

Test>
True :: Bool

AVL32e90945599da53fe4aa1ced3b3250d7.png

–>

AVL3088d9e09c0ac6efb8dbaee96a493e08.png

Feladat: Balra forgatás

leftRot :: T a -> T a
 -- mintaillesztés

Test>
True :: Bool

AVL3088d9e09c0ac6efb8dbaee96a493e08.png

–>

AVL32e90945599da53fe4aa1ced3b3250d7.png

Feladat: Balra-jobbra forgatás

leftRightRot :: T a -> T a

Test>
N (N E 'a' E) 'b' (N E 'c' E) :: T Char

AVLb0afe18aa9b8e11b9fafef7953f290dd.png

–>

AVLb6a1bff966b085784cacffc92d9a34fe.png

Feladat: Jobbra-balra forgatás

rightLeftRot :: T a -> T a

Test>
N (N E 'a' E) 'b' (N E 'c' E) :: T Char

Feladat: Kiegyensúlyozás kis eltérés esetén

balance :: T a -> T a
 -- mintaillesztés, esetszétválasztás, skew, forgatások

Test>
N (N E 'a' E) 'b' (N E 'c' E) :: T Char

A kiegyensúlyozás művelete:

feltétel tennivaló
skew = 2, skew left = -1 balra-jobbra forgatás
skew = 2 jobbra forgatás
skew = -2, skew right = 1 jobbra-balra forgatás
skew = -2 balra forgatás
egyébként semmi

Feladat: Kiegyensúlyozott beszúrás

balIns :: Ord a => a -> T a -> T a
 -- mintaillesztés, esetszétválasztás, rekurzió, balance

Test>
True :: Bool

Ugyanaz, mint ins, de a rekurzív beszúrás után helyreállítjuk a kiegyensúlyozottságot.

Feladat: Rendezés AVL fákkal

sort :: Ord a => [a] -> [a]
 -- inorder, listToTree
listToTree :: Ord a => [a] -> T a
 -- foldr, balIns

Test>
True :: Bool

Hatékonyságnövelés

Készítsünk egy másolatot a forráskódról.

A fa magasságát tároljuk el az algebrai adattípusban:

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

“smart” konstruktor és módosított height:

-- n :: T a -> a -> T a  ->  T a
-- height :: T a -> Int