Info 3.3. Chapter 3.3 Recursive Data Structures Part 2 : Binary Trees
Info Common Recursive Data Structures Linear Lists Binary Trees
Info A Recursive Data Structure Example : A Pedigree FatherMother Name MygrandfatherMygrandmotherMygrandfatherMygrandmother MyfatherMymother Myself
Info Recursive Data Structures Implementation by variant pointers FatherMother Name TYPE Link = POINTER TO Person; Person = RECORD Name : String; Father, Mother : Link END FatherMother Name FatherMother Name FatherMother Name FatherMother Name FatherMother Name
Info Binary Trees Definitions Right subtree Left subtree Leaves ROOT Ordered binary tree : when keys of - all elements of left subtree smaller than Root - all elements of right subtree larger dan Root.
Info Ordered Binary Trees Definitions Ordered binary tree : when all elements of left subtree smaller than Root all elements of right subtree larger than Root. left binary largerall when than Search time < tLog 2 n
Info Ordered Binary Trees Data Declarations for Dictionary TYPE Link = POINTER TO Node; Node = RECORD Key : String; (* other data fields *) Left, Right : Link END;
Info Ordered Binary Trees Dictionary Building PROCEDURE Build(VAR p:Link;x:String); BEGIN IF p = NIL THEN NEW(p); p^.Key:= x; p^.Left:= NIL; p^.Right := NIL ELSE CASE Compare(x,p^.Key) OF less : Build(p^.Left,x) | equal : | greater: Build(p^.Right,x) END (* CASE *) END; (* IF *) END Build;
Info Ordered Binary Trees Node Deletion different situations : a) not present : 8 b) 0 or 1 successor : 1, 2, 4, 5, 7 c) 2 successors : 3, 6
Info Ordered Binary Trees Deletion of node
Info Ordered Binary Trees Deletion of node Root := Rightmost of left subtree
Info Ordered Binary Trees Deletion of node Root := Leftmost of right subtree
Info Ordered Binary Trees Node Deletion Procedure (1) PROCEDURE Delete(VAR p:Link;x:String); VAR q : Link; PROCEDURE RightMost(VAR r:Link);... END RightMost; BEGIN IF p # NIL THEN CASE Compare(x,p^.Key) OF less : Delete(p^.Left,x) | equal : Remove p^ | greater: Delete(p^.Right,x) END (* CASE *) END; (* IF *) END Delete;
Info Ordered Binary Trees Node Deletion Procedure (2) (* Remove p^ *) q := p; IF q^.Right = NIL THEN p:= q^.Left ELSIF q^.Left = NIL THEN p:= q^.Right ELSE RightMost(p^.Left) END; (* IF *) DISPOSE(q)
Info Ordered Binary Trees Node Deletion Procedure (3) (* Remove p^ *) q := p; IF q^.Right = NIL THEN p:= q^.Left ELSIF q^.Left = NIL THEN p:= q^.Right ELSE RightMost(p^.Left) END; (* IF *) DISPOSE(q) pqpq can be NIL
Info Ordered Binary Trees Node Deletion Procedure (4) (* Remove p^ *) q := p; IF q^.Right = NIL THEN p:= q^.Left ELSIF q^.Left = NIL THEN p:= q^.Right ELSE RightMost(p^.Left) END; (* IF *) DISPOSE(q) pqpq
Info Ordered Binary Trees Node Deletion Procedure (5) (* Remove p^ *) q := p; IF q^.Right = NIL THEN p:= q^.Left ELSIF q^.Left = NIL THEN p:= q^.Right ELSE RightMost(p^.Left) END; (* IF *) DISPOSE(q) pqpq
Info Ordered Binary Trees Node Deletion Procedure (6) PROCEDURE RightMost (VAR r:Link); BEGIN IF r^.Right # NIL THEN RightMost(r^.Right) ELSE p^.Key := r^.Key; q := r; r := r^.Left END (* IF *) END RightMost; pqpq r =
Info Ordered Binary Trees Node Deletion Procedure (7) PROCEDURE RightMost (VAR r:Link); BEGIN IF r^.Right # NIL THEN RightMost(r^.Right) ELSE p^.Key := r^.Key; q := r; r := r^.Left END (* IF *) END RightMost; pqpq r =
Info Ordered Binary Trees Node Deletion Procedure (8) PROCEDURE RightMost (VAR r:Link); BEGIN IF r^.Right # NIL THEN RightMost(r^.Right) ELSE p^.Key := r^.Key; q := r; r := r^.Left END (* IF *) END RightMost; X pqpq r X
Info Ordered Binary Trees Node Deletion Procedure (9) (* Remove p^ *) q := p; IF q^.Right = NIL THEN p:= q^.Left ELSIF q^.Left = NIL THEN p:= q^.Right ELSE RightMost(p^.Left) END; (* IF *) DISPOSE(q) X pqpq r
Info Balanced Trees Perfectly balanced tree : | NNLS - NNRS | <= 1 NNLS = Nbr Nodes in Left Subtree NNRS = Nbr Nodes in Right Subtree AVL tree (Adelson-Velskii & Landis) : | HLS-HRS | <= 1 HLS = Height of Left Subtree HRS = Height of Right Subtree
Info Perfectly Balanced Tree All nodes should be perfectly balanced ! 1/00/1 2/2 1/11/0 3/2 0/01/0 1/2 1/11/0 3/2 5/6 4/6 12/11
Info Perfectly Balanced Tree All nodes should be perfectly balanced ! 1/00/1 2/2 1/11/0 3/2 1/0 2/2 1/11/0 3/2 5/6 12/12
Info AVL Balanced Tree AVL condition needs to be satisfied everywhere ! 0/0 1/1 0/0 1/0 2/2 1/1 2/0 2/2 3/3 3/4
Info AVL Balanced Tree AVL condition needs to be satisfied everywhere ! 0/0 1/1 0/0 1/0 2/2 1/10/0 2/1 2/2 3/3 3/4
Info AVL Tree Balancing A B 2 different situations : Case 1 : imbalance between outer subtrees Case 2 : imbalance between inner and outer subtrees
Info AVL Tree Balancing Case 1 : outer imbalance A B A B
Info AVL Tree Balancing Case 2 : inner imbalance (1) A B A B C A B C Inner imbalance can appear in two different situations
Info AVL Tree Balancing Case 2 : inner imbalance (2) A B C AB C
Info AVL Trees Data Declarations for Dictionary TYPE Link = POINTER TO Node; Node = RECORD Key : String; (* other data fields *) Left, Right : Link; Bal : [-1,1] (* -1:left side higher *) (* +1:right side higher *) END;
Info AVL Trees Dictionary Building (1) PROCEDURE BuildAVL (VAR p:Link;x:String;VAR h:BOOLEAN); BEGIN IF p = NIL THEN Insert node; h:= TRUE ELSE CASE Compare(x,p^.Key) OF less : BuildAVL(p^.Left,x,h); IF h THEN adj.bal.left END| equal : h := FALSE | greater: BuildAVL(p^.Right,x,h); IF h THEN adj.bal.right END END (* CASE *) END; (* IF *) END Build;
Info AVL Trees Dictionary Building (2) (* Insert Node *) NEW(p); WITH p^ DO Key := x; Left := NIL; Right := NIL; Bal := 0 END;
Info Adjust Balance Left p^.Bal = rearange 0+1 p^.Bal := h := 0 FALSE TRUE 0 FALSE
Info Rearange +1 p^Bal = p^.Left^.Bal = to be updated updated rearange case 1rearange case 2
Info AVL Trees Dictionary Building (3) (* Adjust Balance Left *) CASE p^.Bal OF +1: p^.Bal := 0; h := FALSE | 0: p^.Bal := -1 (* h := TRUE *) | -1: p1 := p^.Left; (* Rearange *) IF p1^.Bal = -1 THEN rearange, case 1 ELSE rearange, case 2 END; (* IF *) p^.Bal := 0; h := FALSE END; (* CASE *)
Info AVL Trees Rearange, case 1 (1) A B P P1
Info AVL Trees Rearange, case 1 (2) p^.Left := p1^.Right A B P P1
Info AVL Trees Rearange, case 1 (3) p^.Left := p1^.Right; p1^.Right := p; A B P P1
Info AVL Trees Rearange, case 1 (4) p^.Left := p1^.Right; p1^.Right := p; p^.Bal := 0; A B P P1
Info AVL Trees Rearange, case 1 (5) p^.Left := p1^.Right; p1^.Right := p; p^.Bal := 0; p := p1; A B P P1
Info AVL Trees Rearange, case 1 (6) p^.Left := p1^.Right; p1^.Right := p; p^.Bal := 0; p := p1; A B P
Info AVL Trees Rearange, case 2 (1) p2 := p1^.Right; A B C P P1 P2
Info AVL Trees Rearange, case 2 (2) p2 := p1^.Right; p1^.Right := p2^.Left A B C P P1 P2
Info AVL Trees Rearange, case 2 (3) p2 := p1^.Right; p1^.Right := p2^.Left; p2^.Left := p1; A B C P P1 P2
Info AVL Trees Rearange, case 2 (4) p2 := p1^.Right; p1^.Right := p2^.Left; p2^.Left := p1; p^.Left := p2^.Right; A B C P P1 P2
Info AVL Trees Rearange, case 2 (4) p2 := p1^.Right; p1^.Right := p2^.Left; p2^.Left := p1; p^.Left := p2^.Right; p2^.Right := p; A B C P P1 P2
Info AVL Trees Rearange, case 2 (5) p2 := p1^.Right; p1^.Right := p2^.Left; p2^.Left := p1; p^.Left := p2^.Right; p2^.Right := p; CASE p2^.Bal OF -1: P^.Bal := +1; p1^.Bal := 0; | +1: p^.Bal := 0; p1^.Bal := -1 END; (* CASE *) A B C P P1 P2
Info AVL Trees Rearange, case 2 (6) p2 := p1^.Right; p1^.Right := p2^.Left; p2^.Left := p1; p^.Left := p2^.Right; p2^.Right := p; CASE p2^.Bal OF -1: P^.Bal := +1; p1^.Bal := 0; | +1: p^.Bal := 0; p1^.Bal := -1 END; (* CASE *) p := p2; A B C P P1 P2
Info AVL Trees Rearange, case 2 (7) p2 := p1^.Right; p1^.Right := p2^.Left; p2^.Left := p1; p^.Left := p2^.Right; p2^.Right := p; CASE p2^.Bal OF -1: P^.Bal := +1; p1^.Bal := 0; | +1: p^.Bal := 0; p1^.Bal := -1 END; (* CASE *) p := p2; AB C P
Info Tree Traversal InOrder ac b eg f ik j mo n d l h (left subtree) root (right subtree) abcdefghijklmno
Info Tree Traversal InOrder PROCEDURE InOrder(p:link); BEGIN IF p # NIL THEN InOrder(p^.Left); DoWhateverYouWant(p^.data); InOrder(p^.Right) END (* IF *) END InOrder;
Info Tree Traversal PreOrder ac b eg f ik j mo n d l h root (left subtree) (right subtree) hdbacfegljiknmo
Info Tree Traversal PreOrder PROCEDURE PreOrder(p:link); BEGIN IF p # NIL THEN DoWhateverYouWant(p^.data); PreOrder(p^.Left); PreOrder(p^.Right) END (* IF *) END PreOrder;
Info Tree Traversal PostOrder ac b eg f ik j mo n d l h (left subtree) (right subtree) root acbegfdikjmonlh
Info Tree Traversal PostOrder PROCEDURE PostOrder(p:link); BEGIN IF p # NIL THEN PostOrder(p^.Left); PostOrder(p^.Right); DoWhateverYouWant(p^.data); END (* IF *) END PostOrder;
Info Expression Trees a bc /d ef * + - * (a+b/c)*(d-e*f) For evaluation on a stack machine : Postorder = abc/+def*-*
Info Expression Syntax Term Expression + - Factor Term * / Expression () Letter Expression Term Factor
Info Procedure Expression Term Expression + - PROCEDURE Expression (VAR p: Link); VAR q:Link; BEGIN NEW(p);Term(p^Left); IF (Sy = '+') OR (Sy = '-') THEN p^.Op := Sy; GetSy; Expression(p^.Right) ELSE q:= p; p:= p^.Left; DISPOSE(q) END (* IF *) END Expression;
Info Procedure Term Factor Term * / PROCEDURE Term (VAR p: Link); VAR q:Link; BEGIN NEW(p);Factor(p^Left); IF (Sy = '*') OR (Sy = '/') THEN p^.Op := Sy; GetSy; Term(p^.Right) ELSE q:= p; p:= p^.Left; DISPOSE(q) END (* IF *) END Term;
Info Procedure Factor Expression () Letter Factor PROCEDURE Factor (VAR p: Link); BEGIN IF Sy = '(' THEN GetSy; Expression(p); GetSy ELSE NEW(p); p^.Op:= Sy; p^.Left:= NIL; p^.Right:= NIL GetSy END (* IF *) END Factor;
Info (a+b/c)*(d-e/f) ^ Expression PROCEDURE Expression (VAR p: Link);... NEW(p);Term(p^Left);...
Info (a+b/c)*(d-e/f) ^ Term Expression PROCEDURE Term (VAR p: Link);... NEW(p);Factor(p^Left);...
Info (a+b/c)*(d-e/f).^ Factor Term Expression PROCEDURE Factor (VAR p: Link);... IF Sy = '(' THEN GetSy; Expression(p); GetSy...
Info (a+b/c)*(d-e/f).^ Expression Factor Term Expression PROCEDURE Expression (VAR p: Link);... NEW(p);Term(p^Left);...
Info (a+b/c)*(d-e/f).^ Term Expression Factor Term Expression PROCEDURE Term (VAR p: Link);... NEW(p);Factor(p^Left);...
Info (a+b/c)*(d-e/f)..^ Factor Term Expression Factor Term Expression a PROCEDURE Factor (VAR p: Link);... IF Sy = '('... ELSE NEW(p); p^.Op:= Sy; p^.Left:= NIL; p^.Right:= NIL GetSy END (* IF *) END Factor;
Info (a+b/c)*(d-e/f)..^ Term Expression Factor Term Expression a PROCEDURE Term (VAR p: Link);... NEW(p);Factor(p^Left); IF (Sy = '*') OR (Sy = '/')... ELSE q:= p; p:= p^.Left; DISPOSE(q) END (* IF *) END Term;
Info (a+b/c)*(d-e/f)...^ Expression Factor Term Expression + a PROCEDURE Expression (VAR p: Link);... NEW(p);Term(p^Left); IF (Sy = '+') OR (Sy = '-') THEN p^.Op := Sy; GetSy; Expression(p^.Right)...
Info (a+b/c)*(d-e/f)...^ Expression Factor Term Expression PROCEDURE Expression (VAR p: Link);... NEW(p);Term(p^Left);... + a
Info (a+b/c)*(d-e/f)...^ Term Expression Factor Term Expression PROCEDURE Term (VAR p: Link);... NEW(p);Factor(p^Left);... + a
Info (a+b/c)*(d-e/f)....^ Factor Term Expression Factor Term Expression + a b PROCEDURE Factor (VAR p: Link);... IF Sy = '('... ELSE NEW(p); p^.Op:= Sy; p^.Left:= NIL; p^.Right:= NIL GetSy END (* IF *) END Factor;
Info (a+b/c)*(d-e/f).....^ Term Expression Factor Term Expression + / a b PROCEDURE Term (VAR p: Link);... NEW(p);Factor(p^Left); IF (Sy = '*') OR (Sy = '/') THEN p^.Op := Sy; GetSy; Term(p^.Right)...
Info (a+b/c)*(d-e/f).....^ Term Expression Factor Term Expression + / a b PROCEDURE Term (VAR p: Link);... NEW(p);Factor(p^Left);...
Info (a+b/c)*(d-e/f)......^ Factor Term Expression Factor Term Expression + / a b PROCEDURE Factor (VAR p: Link);... IF Sy = '('... ELSE NEW(p); p^.Op:= Sy; p^.Left:= NIL; p^.Right:= NIL GetSy END (* IF *) END Factor; c
Info (a+b/c)*(d-e/f)......^ Term Expression Factor Term Expression + / a b c PROCEDURE Term (VAR p: Link);... NEW(p);Factor(p^Left); IF (Sy = '*') OR (Sy = '/')... ELSE q:= p; p:= p^.Left; DISPOSE(q) END (* IF *) END Term;
Info (a+b/c)*(d-e/f)......^ Term Expression Factor Term Expression + / a b c PROCEDURE Term (VAR p: Link);... IF THEN Term(p^.Right)... END (* IF *) END Term;
Info (a+b/c)*(d-e/f)......^ Expression Factor Term Expression + / a b c PROCEDURE Expression (VAR p: Link);... IF (Sy = '+') OR (Sy = '-')... ELSE q:= p; p:= p^.Left; DISPOSE(q) END (* IF *) END Expression;
Info (a+b/c)*(d-e/f)......^ Expression Factor Term Expression + a / b c PROCEDURE Expression (VAR p: Link);... IF (Sy = '+') OR (Sy = '-')... ELSE q:= p; p:= p^.Left; DISPOSE(q) END (* IF *) END Expression;
Info (a+b/c)*(d-e/f)......^ Expression Factor Term Expression + a / b c PROCEDURE Expression (VAR p: Link);... IF THEN Expression(p^.Right)... END (* IF *) END Expression;
Info (a+b/c)*(d-e/f) ^ Factor Term Expression + a / b c PROCEDURE Factor (VAR p: Link);... IF Sy = '(' THEN GetSy; Expression(p); GetSy END (* IF *) END Factor;
Info (a+b/c)*(d-e/f) ^ Term Expression + a * / b c PROCEDURE Term (VAR p: Link);... NEW(p);Factor(p^Left); IF (Sy = '*') OR (Sy = '/') THEN p^.Op := Sy; GetSy; Term(p^.Right)...
Info (a+b/c)*(d-e/f) ^ Term Expression + a * / b c PROCEDURE Term (VAR p: Link);... NEW(p);Factor(p^Left);...
Info (a+b/c)*(d-e/f) ^ * + a / b c - d / e f