La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Programmazione Mod. B - Alberi - prof. E. Burattini 1.

Presentazioni simili


Presentazione sul tema: "Programmazione Mod. B - Alberi - prof. E. Burattini 1."— Transcript della presentazione:

1 Programmazione Mod. B - Alberi - prof. E. Burattini 1

2 2 A BC D E F A BC D E F Min(A-F) = {A,B,E,F} -->11 A BC D E F Min(A-D) = {A,B,E,F,C,D} -->14 A BC D E F A BC D E F I GRAFI A BC D E F

3 Programmazione Mod. B - Alberi - prof. E. Burattini 3 A BC D E F DEF. Un albero è un grafo senza cicli o circuiti A BC D E F

4 Programmazione Mod. B - Alberi - prof. E. Burattini 4 GLI ALBERI COME STRUTTURE DATI Search Tree - (Albero di ricerca) - Memorizza informazioni in maniera tale che possano essere ritrovate molto velocemente e le operazioni di inserimento e cancellazione nodi sono molto efficienti.

5 Programmazione Mod. B - Alberi - prof. E. Burattini 5 Ricorsione lineare: al più una chiamata ricorsiva nellambito di uno stesso processo ricorsivo. Ricorsione non lineare: più di una chiamata ricorsiva nellambito di uno stesso processo ricorsivo. main F(3) F(1) F(2) F(4) F(2) Fibonacci(4) F(1)F(0) F(1)F(0) main F(3) F(1)F(2) F(1)F(0) Fibonacci(3) FUNCTION Fibonacci(N:integer):integer; BEGIN IF N=0 THEN Fibonacci:=0 ELSE IF N=1 THEN Fibonacci:=1 ELSE Fibonacci:= Fibonacci(N-2) + Fibonacci(N-1) END.

6 Programmazione Mod. B - Alberi - prof. E. Burattini 6 Fibonacci(6) F(6) F(5)F(4) + F(2) F(3) + F(2) F(1) + F(0)F(1) F(3) + F(0)F(1) F(3) F(1) F(2) F(4) F(5) F(3) F(6) F(1)F(2) F(3) F(4) F(2) F(0)F(1) F(0) F(1) F(0)F(1) F(0) F(1) fibon1

7 Programmazione Mod. B - Alberi - prof. E. Burattini 7 ALBERI BINARI Un albero è binario se ogni nodo è al più collegato ad altri due Un albero binario è: –Lalbero vuoto –oppure è costituito da una radice e da un sottoalbero sinistro e da un sottoalbero destro Lalbero è una struttura ricorsiva non lineare. I suoi elementi sono detti nodi

8 Programmazione Mod. B - Alberi - prof. E. Burattini 8 I due disegni rappresentano due alberi uguali ma due alberi binari diversi. Lovvio modo di rappresentare un albero consiste nellassegnare ad ogni nodo due puntatori uno che punta al sottoalbero sinistro ed uno che punta al sottoalbero destro.

9 Programmazione Mod. B - Alberi - prof. E. Burattini 9 Per gestire gli alberi introduciamo un elemento costituito da nodi non più con uno ma con due campi per i puntatori. Attraverso questa struttura potremo rappresentare gli alberi di ricerca binari. Albero Binario Radice (root) Sotto albero

10 Programmazione Mod. B - Alberi - prof. E. Burattini 10 Ugo CarloGiulio EmmaGuidoCarlaMaria AnnaPeppeAngelaNicola

11 Programmazione Mod. B - Alberi - prof. E. Burattini 11 Definiamo sotto albero ogni nodo in cui almeno un puntatore non è uguale a NIL ma punta ad un altro nodo o sotto albero. Definiamo radice di un sotto albero quel nodo che punta ad almeno un altro nodo (NB Negli alberi binari si può al massimo puntare a due nodi (destro e sinistro). La variabile dinamica albero può essere definita attraverso la sua radice, il nodo a partire dal quale si possono raggiungere tutti gli altri nodi della struttura. XXX Tree Left StructureRight Structure Un albero (sotto albero), che punta a NIL e cioè non contiene nodi è detto albero (sotto albero) vuoto.

12 Programmazione Mod. B - Alberi - prof. E. Burattini 12 Albero Binario Radice (root) Sotto albero Cammino (path) X Genitore Figlio Livello del nodo X = 3 Nodi fratelli Altezza dellalbero= Massimo numero di livelli H=3 Foglie

13 Programmazione Mod. B - Alberi - prof. E. Burattini 13 Un albero binario è ordinato quando il campo chiave di ogni nodo è minore del campo chiave di ogni nodo del suo sottoalbero destro ed è maggiore del campo chiave di ogni nodo del suo sottoalbero sinistro. Si parla in questo caso anche di binary search tree (BST).

14 Programmazione Mod. B - Alberi - prof. E. Burattini 14 Sergio Toni LuigiUgo Anna Dora Giulio RiccardoGuido Maria Un albero binario di ricerca (BST) è tale se: - le foglie sinistre hanno un valore del campo chiave inferiore del nodo padre - le foglie destre hanno un valore del campo chiave maggiore del nodo padre Campo chiave Key Field LeftRight Roberto

15 Programmazione Mod. B - Alberi - prof. E. Burattini 15 CONST NullKey= un simbolo o valore per indicare NIL ' ; NullInfo=quando possibile assegna un significato al nodo NIL TYPE KItemType= STRING[20] InfoType= un data type per le informazioni non key BSTP=^BSTNode{puntatore a un nodo} BSTNode = RECORD Key:KItemType; Info: InfoType; Left, Right: BSTP END; VAR TNode:BSTP; LeftKeyInfoRight TNode

16 Programmazione Mod. B - Alberi - prof. E. Burattini 16 Le operazioni che ci interessa definire sono: creazione di un nuovo nodo con un valore assegnato ai campi dati (Key e Info) e NIL ai campi link (Left e Right) dispose (dealloca) di un nodo supposto che esso esista come variabile dinamica selezionare un nodo data una chiave selezionare le Info collegate al nodo selezionare il figlio a sinistra di un dato nodo selezionare il figlio a destra di un dato nodo LeftKeyInfoRight TNode

17 Programmazione Mod. B - Alberi - prof. E. Burattini 17 INTERFACE PROCEDURE MakeTNode(KeyValue:KItemType; TheInfo:InfoType; VAR TNode:BSTP); { Crea un nuovo nodo, assegnando a KeyValue e TheInfo un valore e il valore NIL per i campi Left e Right } PROCEDURE KillTNode(VAR TNode: BSTP); {dispose la memoria allocata per il TNode e poi pone il TNode a NIL. } PROCEDURE GetNodesKey(TNode:BSTP; VAR TheKey:KItemType); {ritorna il key field del nodo puntato da Tnode, se Tnode è NIL allora ritorna il valore di NullKey} PROCEDURE GetNodesInfo(TNode:BSTP; VAR TheInfo:InfoType); {ritorna le informazioni del nodo puntato da Tnode, se Tnode è NIL allora ritorna il valore di NullInfo} CONST NullKey= un simbolo o valore per indicare NIL ' ; NullInfo=quando possibile assegna un significato al nodo NIL TYPE KItemType= STRING[20] InfoType= un data type per le informazioni non key BSTP=^BSTNode{puntatore a un nodo} BSTNode = RECORD Key:KItemType; Info: InfoType; Left, Right: BSTP END; VAR TNode:BSTP; LeftKeyInfoRight TNode

18 Programmazione Mod. B - Alberi - prof. E. Burattini 18 FUNCTION NodesLeftTree(TNode:BSTP) : BSTP; {ritorna il puntatore al sotto albero sinistro di Tnode. Se T Node è NIL allora ritorna NIL } FUNCTION NodesRightTree(TNode:BSTP) : BSTP; {ritorna il puntatore al sotto albero destro di Tnode. Se T Node è NIL allora ritorna NIL } LeftKeyInfoRight TNode CONST NullKey= un simbolo o valore per indicare NIL ' ; NullInfo=quando possibile assegna un significato al nodo NIL TYPE KItemType= STRING[20] InfoType= un data type per le informazioni non key BSTP=^BSTNode{puntatore a un nodo} BSTNode = RECORD Key:KItemType; Info: InfoType; Left, Right: BSTP END; VAR TNode:BSTP;

19 Programmazione Mod. B - Alberi - prof. E. Burattini 19 PROCEDURE MakeTNode(KeyValue:KItemType; TheInfo:InfoType; VAR TNode:BSTP); { Crea un nuovo nodo, assegnando a KeyValue e TheInfo un valore e il valore NIL per i campi Left e Right } BEGIN new(Tnode); WITH TNode^ DO BEGIN Key:=KeyValue; Info:=TheInfo; Left:=NIL; Right:=NIL END END; CONST NullKey= un simbolo o valore per indicare NIL ' ; NullInfo=quando possibile assegna un significato al nodo NIL TYPE KItemType= STRING[20] InfoType= un data type per le informazioni non key BSTP=^BSTNode{puntatore a un nodo} BSTNode = RECORD Key:KItemType; Info: InfoType; Left, Right: BSTP END; LeftKeyInfoRight TNode

20 Programmazione Mod. B - Alberi - prof. E. Burattini 20 PROCEDURE KillTNode(VAR TNode :BSTP); {dispose la memoria allocata per il TNode e poi pone il TNode a NIL. } BEGIN IF Tnode <> NIL THEN BEGIN dispose(TNode); Tnode:=NIL END END; CONST NullKey= un simbolo o valore per indicare NIL ' ; NullInfo=quando possibile assegna un significato al nodo NIL TYPE KItemType= STRING[20] InfoType= un data type per le informazioni non key BSTP=^BSTNode{puntatore a un nodo} BSTNode = RECORD Key:KItemType; Info: InfoType; Left, Right: BSTP END; LeftKeyInfoRight TNode

21 Programmazione Mod. B - Alberi - prof. E. Burattini 21 PROCEDURE GetNodesKey(TNode:BSTP; VAR TheKey:KItemType); {ritorna il key field del nodo puntato da Tnode, se Tnode è NIL allora ritorna il valore di NullKey} BEGIN IF TNode <> NIL THEN TheKey:= TNode ^.Key ELSE TheKey:= NullKey END; CONST NullKey= un simbolo o valore per indicare NIL ' ; NullInfo=quando possibile assegna un significato al nodo NIL TYPE KItemType= STRING[20] InfoType= un data type per le informazioni non key BSTP=^BSTNode{puntatore a un nodo} BSTNode = RECORD Key:KItemType; Info: InfoType; Left, Right: BSTP END; LeftKeyInfoRight TNode

22 Programmazione Mod. B - Alberi - prof. E. Burattini 22 PROCEDURE GetNodesInfo(TNode:BSTP; VAR TheInfo:InfoType); {ritorna le informazioni del nodo puntato da Tnode, se Tnode è NIL allora ritorna il valore di NullInfo} BEGIN IF TNode <> NIL THEN TheInfo:= TNode ^.Info ELSE TheKey:= NullInfo END; CONST NullKey= un simbolo o valore per indicare NIL ' ; NullInfo=quando possibile assegna un significato al nodo NIL TYPE KItemType= STRING[20] InfoType= un data type per le informazioni non key BSTP=^BSTNode{puntatore a un nodo} BSTNode = RECORD Key:KItemType; Info: InfoType; Left, Right: BSTP END; LeftKeyInfoRight TNode

23 Programmazione Mod. B - Alberi - prof. E. Burattini 23 FUNCTION NodesLeftTree(TNode:BSTP) : BSTP; {ritorna il puntatore al sotto albero sinistro di Tnode. Se T Node è NIL allora ritorna NIL } BEGIN IF Tnode <> NIL THEN NodesLeftTree:=Tnode^.Left ELSE NodesLeftTree:=NIL END: CONST NullKey= un simbolo o valore per indicare NIL ' ; NullInfo=quando possibile assegna un significato al nodo NIL TYPE KItemType= STRING[20] InfoType= un data type per le informazioni non key BSTP=^BSTNode{puntatore a un nodo} BSTNode = RECORD Key:KItemType; Info: InfoType; Left, Right: BSTP END; LeftKeyInfoRight TNode

24 Programmazione Mod. B - Alberi - prof. E. Burattini 24 FUNCTION NodesRightTree(TNode:BSTP) : BSTP; {ritorna il puntatore al sotto albero destro di Tnode. Se T Node è NIL allora ritorna NIL } BEGIN IF Tnode <> NIL THEN NodesRightTree:=Tnode^. Right ELSE NodesRightTree:=NIL END: CONST NullKey= un simbolo o valore per indicare NIL ' ; NullInfo=quando possibile assegna un significato al nodo NIL TYPE KItemType= STRING[20] InfoType= un data type per le informazioni non key BSTP=^BSTNode{puntatore a un nodo} BSTNode = RECORD Key:KItemType; Info: InfoType; Left, Right: BSTP END; LeftKeyInfoRight TNode

25 Programmazione Mod. B - Alberi - prof. E. Burattini 25 Pseudo codice per un algoritmo generalizzato di selezione nodi PROCEDURE GetNodeField(ANode:NodeP; VAR FieldVar: FieldType) IF ANode <> NIL THEN FieldVar ANode^.identificatore della variabile di campo selezionata ELSE FieldVar NullValue

26 Programmazione Mod. B - Alberi - prof. E. Burattini 26 Gli stessi dati possono essere contenuti in alberi binari di forma diversa. Ugo Toni Maria Anna Dora SergioGiulio Guido Luigi Riccardo Anna Dora Sergio Giulio Luigi Guido Maria Riccardo Toni Ugo Sergio Toni Luigi Ugo Anna Dora Giulio RiccardoGuido Maria

27 Programmazione Mod. B - Alberi - prof. E. Burattini 27 Un albero si dice bilanciato se il livello di tutte le foglie è uguale allaltezza dellalbero o a questa stessa altezza meno 1. H=3 L=3 Foglie H=3 L=3 L=2

28 Programmazione Mod. B - Alberi - prof. E. Burattini 28 H=5 Foglie L=3 L=2 L=4 L=5 L=1 L=0

29 Programmazione Mod. B - Alberi - prof. E. Burattini 29 Un albero bilanciato si esplora per fare una ricerca in un numero di passi inferiore a quello necessario per esplorare un albero non bilanciato. Nellesempio supponiamo di cercare Riccardo: Ugo Toni Maria Anna Dora SergioGiulio Guido Luigi Riccardo Anna Dora Sergio Giulio Luigi Guido Maria Riccardo Toni Ugo Sergio Toni Luigi Ugo Anna Dora Giulio RiccardoGuido Maria Roberto 4 passi di computazione 2 passi di computazione 6 passi di computazione

30 Programmazione Mod. B - Alberi - prof. E. Burattini 30 In un albero bilanciato il tempo massimo di ricerca è di O(log 2 (N)) dove N è il numero di nodi. Se un albero bilanciato ha M livelli, il numero di nodi di cui è formato può variare tra 2 M e 2 (M+1) -1.

31 Programmazione Mod. B - Alberi - prof. E. Burattini 31 ALBERO BILANCIATO CON M LIVELLI Totale Nodi N° NODI N° NODI 0 1 M Totale Nodi

32 Programmazione Mod. B - Alberi - prof. E. Burattini 32 Serie geometrica

33 Programmazione Mod. B - Alberi - prof. E. Burattini 33 Supponiamo sia assegnata una lista di N oggetti tra i quali esiste una relazione dordine. Se riusciamo a inserire questi oggetti in un albero di ricerca bilanciato allora il numero di passi per trovare un qualunque oggetto è limitato da O(log 2 (N)). Se questo non avviene il caso peggiore in cui possiamo trovarci è pari a O(N). Si può dimostrare che un albero di ricerca binario costruito in maniera casuale, quindi non necessariamente bilanciato, effettua in media un numero di passi per effettuare la ricerca pari a 1.36 * O(log 2 (N)). Toni Maria Ugo Riccardo Anna Dora Sergio Giulio Luigi Guido

34 Programmazione Mod. B - Alberi - prof. E. Burattini 34 ESEMPIO Supponiamo di avere un albero di tipo BST, chiamiamo con Root il primo nodo. Scrivere una funzione LeftMost che fornisca il puntatore del nodo più a sinistra che si incontra a partire da Root. Sergio Toni Anna Dora Giulio RiccardoGuido Maria Roberto LeftKeyInfoRight CONST NullKey= un simbolo o valore per indicare NIL ' ; NullInfo=quando possibile assegna un significato al nodo NIL TYPE KItemType= STRING[20] InfoType= un data type per le informazioni non key BSTP=^BSTNode{puntatore a un nodo} BSTNode = RECORD Key:KItemType; Info: InfoType; Left, Right: BSTP END; VAR Root:BSTP; Root

35 Programmazione Mod. B - Alberi - prof. E. Burattini 35 CONST NullKey= un simbolo o valore per indicare NIL ' ; NullInfo=quando possibile assegna un significato al nodo NIL TYPE KItemType= STRING[20] InfoType= un data type per le informazioni non key BSTP=^BSTNode{puntatore a un nodo} BSTNode = RECORD Key:KItemType; Info: InfoType; Left, Right: BSTP END; VAR Root:BSTP; FUNCTION LeftMost(Root: BSTP): BSTP; VAR NodoEsaminato:BSTP; BEGIN IF EmptyTree(Root) THEN NodoEsaminato = NIL; ELSE NodoEsaminato = Root; WHILE NodesLeftTree(NodoEsaminato) <> NIL DO NodoEsaminato = NodesLeftTree(NodoEsaminato) ; LeftMost: = NodoEsaminato END: Definizione della funzione Definizione delle variabili Verifica se lalbero è vuoto Cerca il nodo FUNCTION NodesLeftTree(TNode:BSTP) : BSTP; BEGIN IF Tnode <> NIL THEN NodesLeftTree:=Tnode^.Left ELSE NodesLeftTree:=NIL END:

36 Programmazione Mod. B - Alberi - prof. E. Burattini 36 { Dato un albero binario calcolare il puntatore dell'ultimo nodo a sinistra.} Program AlberoSin(input,output); uses Crt, Alberi0; CONST var Albero,: BSTP; FUNCTION ChiaveNodiSin(Tree:BSTP):BSTP; BEGIN IF EmptyTree(NodesLeftTree(Tree)) THEN ChiaveNodiSin:=Tree ELSE BEGIN ChiaveNodiSin:=ChiaveNodiSin(NodesLeftTree(Tree)); END; {************** MAIN***********} begin writeln('Costruiamo un Albero. '); BuildNameTree(Albero); WriteAlbero(Albero); writeln(' La chiave e'' ', ChiaveNodiSin(Albero)^.Key); end.

37 Programmazione Mod. B - Alberi - prof. E. Burattini 37 OPERAZIONI SUI BST Ogni nodo di un BST punta ad altri due nodi, ciascuno dei quali è una variabile dinamica di tipo record. Quindi una variabile di tipo BSTType, cioè un puntatore alla radice di un BST, che è a sua volta una variabile BST, può essere passata da un blocco ad un altro. In altre parole dato un nodo di un BST, questo è radice per i suoi sottoalberi e i nodi a cui punta sono a loro volta radici di altri sottoalberi. Pertanto possiamo adoperare ricorsivamente queste variabili. Poiché una variabile BST può essere interpretata o come nodo di un BST o come un sotto albero di un BST, pur essendo variabili dello stesso tipo parleremo nel primo caso di un tipo BSTP (puntatore a un nodo) e nel secondo caso di un tipo BSTType (puntatore a un albero) CONST NullKey= un simbolo o valore per indicare NIL ' ; NullInfo=quando possibile assegna un significato al nodo NIL TYPE KItemType= STRING[20] InfoType= un data type per le informazioni non key BSTP=^BSTNode{puntatore a un nodo} BSTNode = RECORD Key:KItemType; Info: InfoType; Left, Right: BSTP END; BSTType=BSTP VAR NomeAlbero:BSTType Nodo:BSTP; LeftKeyInfoRight NomeAlbero

38 Programmazione Mod. B - Alberi - prof. E. Burattini 38 INTERFACE PROCEDURE MakeTree(VAR Tree: BSTType); {inizializza a NIL lalbero, creando un albero vuoto} PROCEDURE AddTNode(KeyValue:KItemType; TheInfo:InfoType;VAR Tree: BSTType; VAR Done:boolean); {aggiunge un nodo allalbero rispettando la struttura di un BST, se il KeyValue è già presente nellalbero non fa nulla e Done risulta False} PROCEDURE DeleteTNode(KeyValue:KItemType;VAR Tree: BSTType; VAR Done:boolean); {elimina il nodo con chiave KeyValue, se esso non esiste Done risulta False} FUNCTION SearchTNode(Tree: BSTType; KeyValue:KItemType): BSTP; {cerca il nodo con chiave KeyValue, se esso non esiste ritorna NIL} FUNCTION EmptyTree(Tree: BSTType): boolean; {ritorna vero se lalbero è vuoto}

39 Programmazione Mod. B - Alberi - prof. E. Burattini 39 IMPLEMENTATION PROCEDURE MakeTree(VAR Tree: BSTType); {inizializza a NIL lalbero, creando un albero vuoto} BEGIN Tree:=NIL END; FUNCTION EmptyTree(Tree: BSTType): boolean; {ritorna vero se lalbero è vuoto} BEGIN EmptyTree:=Tree=NIL END;

40 Programmazione Mod. B - Alberi - prof. E. Burattini 40 ESEMPIO: COSTRUZIONE DI UN BST DI NOMI LeftKeyInfoRight TNode CONST NullKey= ' ; NullInfo= TYPE KItemType= STRING[20] InfoType= STRING[20] BSTP=^BSTNode{puntatore a un nodo} BSTNode = RECORD {variabile dinamica per un nodo} Key:KItemType; Info: InfoType; Left, {radice del sottoalbero di sinistra} Right: BSTP {radice del sottoalbero di destra} END; BSTType=BSTP; {definizione per la variabile albero} VAR NameTree:BSTType;

41 Programmazione Mod. B - Alberi - prof. E. Burattini 41 COSTRUZIONE DI UN BST DI NOMI Sergio Toni Anna Dora Giulio RiccardoGuido Maria Roberto Maria Giulio Sergio Dora Guido Riccardo Toni Anna Roberto return Supponiamo che vengano introdotti da tastiera i seguenti nomi:

42 Programmazione Mod. B - Alberi - prof. E. Burattini 42 Pseudo codice MakeTree(NameTree) introduci Nome WHILE Nome <> NullKey DO AddTNode(Nome, NullInfo, NameTree, Success) IF NOT Success THEN segnala che il Nome esiste già introduci il nome mostra il messaggio di fine lavoro

43 Programmazione Mod. B - Alberi - prof. E. Burattini 43 CONST NullKey= ' ; NullInfo= TYPE KItemType= STRING[20] InfoType= STRING[20] BSTP=^BSTNode BSTNode = RECORD Key:KItemType; Info: InfoType; Left, Right: BSTP END; BSTType=BSTP; VAR NameTree:BSTTYpe; PROCEDURE BuildNameTree(VAR NameTree: BSTType); {costruisce un albero a cui assegna un Nome dato in input} VAR Nome:KItemType; Success: boolean; BEGIN MakeTree(NameTree); write( Dammi un nome : ); readln(Nome); WHILE Nome <> NullKey DO BEGIN AddTNode(Nome, NullInfo, NameTree, Success); IF NOT Success THEN writeln( Nome, esiste già); write( Dammi un nome : ); readln(Nome) END; writeln( Lalbero è stato piantato); END;

44 Programmazione Mod. B - Alberi - prof. E. Burattini 44 DEFINIZIONE DI ATTRAVERSAMENTO DI UN BST Visitare tutti i nodi di un BST di nomi, a partire dalla radice, e elencare i nomi in ordine crescente (o decrescente). Anna Dora Giulio Guido Maria Riccardo Roberto Sergio Toni Sergio Toni Anna Dora Giulio RiccardoGuido Maria Roberto

45 Programmazione Mod. B - Alberi - prof. E. Burattini 45 MOSTRA IL CONTENUTO DI UN BST Mostra le Chiavi (KeyItem) di tutti i nodi del sottoalbero sinistro di NameTree Mostra la Chiave (KeyItem) della radice di NameTree Mostra le Chiavi (KeyItem) di tutti i nodi del sottoalbero destro di NameTree Sergio Toni Anna Dora Giulio RiccardoGuido Maria Roberto ShowTree(NodesLeftTree(NameTree)); GetNodesKey(NameTree, Nome); Writeln(Nome) ShowTree(NodesRightTree(NameTree)); Pseudo codice

46 Programmazione Mod. B - Alberi - prof. E. Burattini 46 La procedura ShowTree(NameTree) è una procedura ricorsiva il cui caso base è rappresentato dallalbero vuoto (EmptyTree). In altre parole il processo di pop inizia non appena largomento di ShowTree(NameTree) è un albero vuoto. PROCEDURE ShowTree(NameTree: BSTType); VAR NodesKey: KItemType; BEGIN IF NOT EmptyTree(NameTree) THEN BEGIN ShowTree(NodesLeftTree(NameTree)); GetNodesKey(NameTree, Nome); writeln(Nome) ShowTree(NodesRightTree(NameTree)); END END;

47 Programmazione Mod. B - Alberi - prof. E. Burattini 47 PROGRAM WriteAlbero(Tree:BSTP); PROCEDURE Wa(Tree:BSTP;I:integer); VAR J:integer; BEGIN IF NOT EmptyTree(Tree) THEN BEGIN Wa(NodesRightTree(Tree),I+1); FOR J:=1 TO I DO write(' '); write(Tree^.Key); writeln; Wa(NodesLeftTree(Tree),I+1); END; {************* MAIN***********} BEGIN IF NOT EmptyTree(Tree) THEN Wa(Tree,1) END; Esercizio Analizzare la seguente procedure ricorsiva e descrivere il suo comportamento con un esempio

48 Programmazione Mod. B - Alberi - prof. E. Burattini 48 Ricorsione lineare: al più una chiamata ricorsiva nellambito di uno stesso processo ricorsivo. Ricorsione non lineare: più di una chiamata ricorsiva nellambito di uno stesso processo ricorsivo. main F(3) F(1) F(2) F(4) F(2) Fibonacci(4) F(1)F(0) F(1)F(0) main F(3) F(1)F(2) F(1)F(0) Fibonacci(3) FUNCTION Fibonacci(N:integer):integer; BEGIN IF N=0 THEN Fibonacci:=0 ELSE IF N=1 THEN Fibonacci:=1 ELSE Fibonacci:= Fibonacci(N-2) + Fibonacci(N-1) END.

49 Programmazione Mod. B - Alberi - prof. E. Burattini 49 Fibonacci(6) F(6) F(5)F(4) + F(2) F(3) + F(2) F(1) + F(0)F(1) F(3) + F(0)F(1) F(3) F(1) F(2) F(4) F(5) F(3) F(6) F(1)F(2) F(3) F(4) F(2) F(0)F(1) F(0) F(1) F(0)F(1) F(0) F(1) fibon1

50 Programmazione Mod. B - Alberi - prof. E. Burattini 50 RICERCA DI UN DATO SU UN BST Sergio Toni Anna Dora Giulio RiccardoGuido Maria Roberto Riccardo ?????????

51 Programmazione Mod. B - Alberi - prof. E. Burattini 51 FUNCTION Binary (VAR Studenti: StudenteRecord; MatrCercata:StringaNome; Lo, Hi :integer) :integer VAR Mid:integer; BEGIN IF Lo>Hi THEN Binary := 0 ELSE BEGIN Mid (Lo+Hi) DIV 2 IF Studenti[Mid].Matr=MatrCercata THEN Binary := Mid ELSE IF Studenti[Mid].Matr

52 Programmazione Mod. B - Alberi - prof. E. Burattini 52 FUNCTION SearchTNode(Tree: BSTType; KeyValue:KItemType): BSTP; {cerca il nodo con chiave KeyValue, se esso non esiste ritorna NIL} VAR TheKey: KItemType; BEGIN IF EmptyTree(Tree) THEN SearchTNode NIL ELSE BEGIN GetNodesKey(Tree, TheKey) IF TheKey = KeyValue THEN SearchTNode Tree ELSE IF KeyValue < TheKey SearchTNode SearchTNode(NodesLeftTree(Tree), KeyValue) ELSE SearchTNode SearchTNode(NodesRightTree(Tree), KeyValue) END END; TheKey:= TNode ^.Key NodesLeftTree:=Tnode^.Left NodesLeftRight:=Tnode^. Right

53 Programmazione Mod. B - Alberi - prof. E. Burattini 53 ESERCIZIO Sia assegnato un albero binario, scrivere un algoritmo tale che sposti ogni figlio sinistro nel corrispondente figlio destro e viceversa. A BC DEF GH A CB DFE HG

54 Programmazione Mod. B - Alberi - prof. E. Burattini 54 { Scrivere un algoritmo che dato un albero binario lo trasformi invertendo i figli sinistro e destro di ogni nodo } Program AlberoScambio(input,output); uses Crt, Alberi0; CONST NKey=-100; var Albero,Temp : BSTP; Item: KItemType; Chiave:KItemType; Info:InfoType; Done:boolean; PROCEDURE ScambiaNodi(Tree:BSTP); BEGIN IF NOT EmptyTree(Tree) THEN BEGIN ScambiaNodi(NodesLeftTree(Tree)); ScambiaNodi(NodesRightTree(Tree)); Temp:=Tree^.Left; Tree^.Left:= Tree^.Right; Tree^.Right:=Temp; END; {************** MAIN***********} begin clrscr; writeln('Costruiamo un Albero. '); BuildNameTree(Albero); WriteAlbero(Albero); readln; {scambia nodi} ScambiaNodi(Albero); writeln(' SCAMBIO '); WriteAlbero(Albero); writeln(' FINE'); readln; end.

55 Programmazione Mod. B - Alberi - prof. E. Burattini 55 AGGIUNTA DI UN DATO SU UN BST Sergio Toni Anna Dora Giulio RiccardoGuido Maria Roberto Rolando Per aggiungere un nodo a un BST è necessario innanzitutto verificare che lItem non esiste già, perché in tal caso il nodo non viene aggiunto. Se non esiste bisogna trovare la sua corretta posizione nellalbero, cioè il suo genitore e mettere poi i figli a NIL.

56 Programmazione Mod. B - Alberi - prof. E. Burattini 56 PROCEDURE AddTNode(KeyValue:KItemType; TheInfo:InfoType;VAR Tree: BSTType; VAR Done:boolean); {aggiunge una foglia allalbero rispettando la struttura di un BST, se il KeyValue è già presente nellalbero non fa nulla e Done risulta False} PROCEDURE DeleteTNode(KeyValue:KItemType;VAR Tree: BSTType; VAR Done:boolean); {elimina il nodo con chiave KeyValue ricostruendo la struttura BST. Se il Nodo non esiste Done risulta False}

57 Programmazione Mod. B - Alberi - prof. E. Burattini 57 Pseudo Codice di AddTNode Search(Tree, KeyValue, TNode, Parent) IF NOT EmptyTree(TNode) THEN Done FALSE ELSE crea e aggiungi un nuovo nodo come figlio del nodo Parent Done TRUE Se il nodo che vogliamo inserire, avente un certo KeyValue, esiste, allora Tnode non è vuoto e quindi non lo aggiungiamo altrimenti lo aggiungiamo Cerca sullalbero Tree il puntatore (TNode) al nodo con KeyValue, se esiste ritorna anche il padre, Parent, del nodo cercato altrimenti TNode=NIL..

58 Programmazione Mod. B - Alberi - prof. E. Burattini 58 PROCEDURE AddTNode(KeyValue:KItemType; TheInfo:InfoType;VAR Tree: BSTType; VAR Done: boolean); VAR Tnode, Parent : BSTP; {deve valere NIL se il nodo esiste già} ParentsKey: KeyItemType;{genitore del nodo da aggiungere} BEGIN Search(Tree, KeyValue, TNode, Parent) IF NOT EmptyTree(TNode) THEN{il nodo esiste già} Done := FALSE ELSE {crea e aggiungi un nuovo nodo come figlio del nodo Parent} BEGIN IF EmptyTree(Parent) THEN{il nuovo nodo sarà la radice} MakeTNode(KeyValue, TheInfo, Tree) ELSE BEGIN GetNodesKey(Parent, ParentsKey); {puntatore di ParentsKey} IF ParentsKey > KeyValue THEN {il nuovo nodo va a left} MakeTNode(KeyValue, TheInfo, Parent^.Left) ELSE {il nuovo nodo va a right} MakeTNode(KeyValue, TheInfo, Parent^.Right) END; Done := TRUE END END;

59 Programmazione Mod. B - Alberi - prof. E. Burattini 59 Search Search(Tree, KeyValue, TNode, Parent) Obiettivo: cercare un cammino verso un determinato nodo dellalbero. Se il nodo non esiste ritorna NIL. Se esiste ritorna il puntatore al nodo individuato e quello di suo padre. Pseudo Codice Parent NIL {la root non ha genitori} TNode Tree {la radice è il primo nodo esaminato} GetNodesKey(TNode, NodesKey){estrai la chiave del nodo in esame} WHILE ci sono altri nodi da esaminare AND non si è ancora trovato il nodo DO Parent TNode Tnode il sottoalbero legato al KeyValue GetNodesKey(TNode, NodesKey){estrai la chiave del nodo in esame} EmptyTree(TNode) NodesKey <> KeyValue IF NodesKey > KeyValue THEN TNode radice del sottoalbero sinistro ELSE TNode radice del sottoalbero destro Il padre dellultimo nodo esaminato durante la ricerca di KeyValue

60 Programmazione Mod. B - Alberi - prof. E. Burattini 60 PROCEDURE Search(Tree: BSTT, KeyValue: KItemType, VAR TNode, Parent: BSTP); VAR NodesKey: KItemType; BEGIN Parent:= NIL; {la root non ha genitori} Tnode:= Tree; {la radice è il primo nodo esaminato} GetNodesKey(TNode, NodesKey);{estrai la chiave del primo nodo} WHILE NOT EmptyTree(TNode) AND (NodesKey <> KeyValue) DO BEGIN Parent:= Tnode; IF NodesKey > KeyValue THEN Tnode:= NodesLeftTree(TNode) ELSE Tnode:= NodesRightTree(TNode); GetNodesKey(TNode, NodesKey){estrai la chiave del nodo in esame} END END; Ricordarsi che GetNodesKey nel caso trovi NIL ritorna NullKey

61 Programmazione Mod. B - Alberi - prof. E. Burattini Aggiungi 17 Tnode NIL Pseudo Codice Parent NIL {la root non ha genitori} TNode Tree {la radice è il primo nodo esaminato} GetNodesKey(TNode, NodesKey){estrai la chiave del nodo in esame} WHILE ci sono altri nodi da esaminare AND non si è ancora trovato il nodo DO Parent TNode Tnode il sottoalbero legato al KeyValue GetNodesKey(TNode, NodesKey){estrai la chiave del nodo in esame} Aggiungi Tnode = NIL BEGIN Search(Tree, KeyValue, TNode, Parent) IF NOT EmptyTree(TNode) THEN{il nodo esiste già} Done := FALSE ELSE {crea e aggiungi un nuovo nodo come figlio del nodo Parent} BEGIN IF EmptyTree(Parent) THEN MakeTNode(KeyValue, TheInfo, Tree) {il nuovo nodo sarà la radice} ELSE BEGIN GetNodesKey(Parent, ParentsKey); IF ParentsKey > KeyValue THEN {il nuovo nodo va a sinistra} MakeTNode(KeyValue, TheInfo, Parent^.Left) ELSE {il nuovo nodo va a destra} MakeTNode(KeyValue, TheInfo, Parent^.Right) END; Done := TRUE END END; AddTNode Search

62 Programmazione Mod. B - Alberi - prof. E. Burattini 62 ESERCIZIO {Scrivere una procedura o funzione che assegnato un albero binario di interi e un livello Lev conti il numero num di tutti i nodi presenti in quel livello. } lev riga

63 Programmazione Mod. B - Alberi - prof. E. Burattini 63 T19, riga=0, lev=3, num= lev riga procedure ContaLivello(Tree:BSTP; riga,lev:integer;VAR num:integer); BEGIN if not (emptytree(tree)) THEN BEGIN IF riga=lev THEN num:=num+1; IF riga

64 Programmazione Mod. B - Alberi - prof. E. Burattini 64 Problema Realizzare una procedura che elimina il nodo con chiave KeyValue Pseudo Codice Search(Tree, KeyValue, Candidate, Parent) GetNodesKey(Candidate, CandsKey) IF CandsKey <> KeyValue THEN Done FALSE ELSE riorganizza lalbero dopo aver rimosso Candidate KillTNode(Candidate) Done TRUE Ritorna la chiave CandsKey puntata da Candidate Implica che se cerco di nuovo un nodo con chiave CandsKey non lo trovo e che lalbero che resta, deallocando il nodo Candidate, è ancora un BST

65 65 Analizziamo il problema della riorganizzazione dellalbero una volta eliminato un nodo. Caso a- il nodo da eliminare ha il sotto albero sinistro vuoto. QQQ RRR Parent Candidate leftright Sergio Toni Anna Dora Giulio RiccardoGuido Maria Roberto Sergio Toni Anna Dora Giulio Riccardo Guido Maria Roberto Caso b- il nodo da eliminare ha il sotto albero destro vuoto. La procedura è analoga alla precedente. Eliminare Riccardo

66 Programmazione Mod. B - Alberi - prof. E. Burattini 66 Pseudo Codice IF EmptyTree(NodesLeftTree(Candidate)) THEN LinkParent(Candidate, NodesRightTree(Candidate), Parent, Tree) ELSE IF EmptyTree(NodesRightTree(Candidate)) THEN LinkParent(Candidate, NodesLeftTree(Candidate), Parent, Tree) ELSE continua a riorganizzare lalbero PROCEDURE LinkParent (OldChild, NewChild, Parent: BSTP;VAR Tree: BSTType); {riorganizza lalbero BST dopo leliminazione di un nodo} QQQ RRR Parent Candidate leftright

67 Programmazione Mod. B - Alberi - prof. E. Burattini 67 Riassunto dei tipi di cancellazione New Old Parent Old New PROCEDURE DeleteTNode(KeyValue:KItemType;VAR Tree: BSTType; VAR Done:boolean); {elimina il nodo con chiave KeyValue ricostruendo la struttura BST. Se il Nodo non esiste Done risulta False}

68 Programmazione Mod. B - Alberi - prof. E. Burattini 68 Nel caso in cui il Nodo da cancellare ha sia il sotto albero di sinistra che quello di destra allora si procede come segue: si sostituisce al nodo da cancellare o il nodo di valore maggiore del suo sottoalbero di sinistra o quello di valore minore del suo sotto albero di destra. Se questo nodo ha a sua volta un sottoalbero di destra e uno di sinistra ci si comporta nei suoi confronti come se fosse un nodo da cancellare e quindi si esegue la stessa procedura sopra descritta. Nodo da cancellare

69 Programmazione Mod. B - Alberi - prof. E. Burattini 69 PROCEDURE DeleteTNode(KeyValue: KItemType; VAR Tree:BSTType; VAR Done:boolean); VAR Candidate, {puntatore al nodo candidato per la cancellatura} Parent, {puntatore al genitore del nodo candidato} OldCandidate :BSTP; CandsKey: KItemType: BEGIN Done:= TRUE Search(Tree, KeyValue, Candidate, Parent); GetNodesKey(Candidate, CandsKey); IF CandsKey<> KeyValue THEN Done:=FALSE ELSE IF EmptyTree(NodesLeftTree(Candidate)) THEN LinkParent(Candidate, NodesRightTree(Candidate), Parent, Tree) ELSE IF EmptyTree(NodesRightTree(Candidate)) THEN LinkParent(Candidate, NodesLeftTree(Candidate), Parent, Tree) ELSE GetNewCandidate(KeyValue, Candidate, Tree); KillTNode(Candidate); END; Fornisce il puntatore della Key da eliminare e quello del suo genitore. Se Candidate=NIL significa che la Key non cè. Fornisce la chiave CandsKey di Candidate Se il sottoalbero sinistro è vuoto collega il genitore di candidate con la radice del sotto albero destro. Se Parent=NIL, cioè si vuole cancellare la radice allora poni in Tree la radice del sotto albero destro. Se il sottoalbero destro è vuoto collega il genitore di candidate con la radice del sotto albero sinistro. Se Parent=NIL, cioè si vuole cancellare la radice allora poni in Tree la radice del sotto albero sinistro. Se nessuno dei sue sotto alberi è vuoto allora chiama GetNewCandidate Non cè niente da cancellare

70 Programmazione Mod. B - Alberi - prof. E. Burattini 70 PROCEDURE LinkParent(OldChild, NewChild, Parent: BSTP; VAR Tree:BSTType); {collega il nodo genitore con il sottoalbero connesso al nodo da cancellare} BEGIN IF Parent=NIL THEN{sostituiamo la root} Tree:= NewChild ELSE IF OldChild = NodesLeftTree(Parent) THEN Parent^.Left:=NewChild{sostituiamo al genitore il figlio sinistro} ELSE Parent^.Right:=NewChild{sostituiamo al genitore il figlio destro} END; New Old Parent Old New

71 Programmazione Mod. B - Alberi - prof. E. Burattini 71 Problema Realizzare una procedura che elimina il nodo con chiave KeyValue Pseudo Codice Search(Tree, KeyValue, Candidate, Parent) GetNodesKey(Candidate, CandsKey) IF CandsKey <> KeyValue THEN Done FALSE ELSE riorganizza lalbero dopo aver rimosso Candidate KillTNode(Candidate) Done TRUE Ritorna la chiave CandsKey puntata da Candidate Implica che se cerco di nuovo un nodo con chiave CandsKey non lo trovo e che lalbero che resta, deallocando il nodo Candidate, è ancora un BST Pseudo Codice IF EmptyTree(NodesLeftTree(Candidate)) THEN LinkParent(Candidate, NodesRightTree(Candidate), Parent, Tree) ELSE IF EmptyTree(NodesRightTree(Candidate)) THEN LinkParent(Candidate, NodesLeftTree(Candidate), Parent, Tree) ELSE continua a riorganizzare lalbero

72 Programmazione Mod. B - Alberi - prof. E. Burattini 72 RICAPITOLANDO Search(Tree, Key, Candidate, Parent) fornisce il puntatore Candidate del node che ha chiave Key e il puntatore Parent come padre a b Key=b Candidate=P(b) Parent=P(a) LinkParent(Old, New, Parent, Tree) collega New con Parent eliminando OLD, se Parent=NIL, cioè Old=Tree è la radice allora mette New al posto di Old e quindi di Tree Parent New Old New

73 73 Pesudo codice di DeleteTNode(Key, Tree, Done) Search(Tree, Key, Candidate, Parent) Fornisce il puntatore della Key da eliminare e quello del suo genitore. Se Candidate=NIL significa che la Key non cè. GetNodesKey(Candidate, CandsKey) Fornisce la chiave CandsKey di Candidate IF CandsKey<> Key Se la chiave trovata e quella di partenza non corrispondono CandsKey=NIL allora esci ELSE Se il sottoalbero sinistro è vuoto collega il genitore di candidate con la radice del sotto albero destro. Se Parent=NIL, cioè si vuole cancellare la radice allora poni in Tree la radice del sotto albero destro. Se nessuno dei due sotto alberi è vuoto allora chiama GetNewCandidate Se il sottoalbero destro è vuoto collega il genitore di candidate con la radice del sotto albero sinistro. Se Parent=NIL, cioè si vuole cancellare la radice allora poni in Tree la radice del sotto albero sinistro.

74 Programmazione Mod. B - Alberi - prof. E. Burattini Nodo da cancellare old candidate parent

75 Programmazione Mod. B - Alberi - prof. E. Burattini 75 Pseudo Codice di GetNewCandidate OldCandidate Candidate Search(NodesRightTree(OldCandidate), KeyValue, Dummy, Candidate) OldCandidate^.Key Candidate^.Key CandsKey := Candidate^.Key; Search(NodesRightTree(OldCandidate), CandsKey, Dummy, Parent) IF Parent = NIL THEN LinkParent(Candidate,NodesRightTree(Candidate), OldCandidate, Tree) ELSE LinkParent(Candidate,NodesRightTree(Candidate), Parent, Tree) Ricerca OldCandidate a partire dal suo nodo destro con la conseguenza che trova il più piccolo di questo sottoalbero (Candidate) (Dummy vale NIL) Sostituisci il nodo da cancellare con CandidateRiprendi la chiave del nodo spostato Cerca il più piccolo nodo del sottoalbero destro del nodo spostato a partire dalla sua primitiva posizione Collega il sottoalbero destro con il padre del nodo spostato Se il nodo da cancellare è la root e segue immediatamente il padre allora collega il sottoalbero destro con la root

76 Programmazione Mod. B - Alberi - prof. E. Burattini 76 PROCEDURE GetNewCandidate(KeyValue: KItemType; VAR Candidate:BSTP; VAR Tree:BSTType); VAR Dummy, {variabile ausiliare per la chiamata alla Search} Parent, OldCandidate :BSTP; CandsKey: KItemType: BEGIN OldCandidate := Candidate Search(NodesRightTree(OldCandidate), KeyValue, Dummy, Candidate) OldCandidate^.Info := Candidate^.Info ; OldCandidate^.Key := Candidate^.Key; CandsKey := Candidate^.Key; Search(NodesRightTree(OldCandidate), CandsKey, Dummy, Parent); IF Parent= NIL THEN LinkParent(Candidate,NodesRightTree(Candidate), OldCandidate, Tree) ELSE LinkParent(Candidate,NodesRightTree(Candidate), Parent, Tree) END;

77 Search(Tree, KeyValue, Candidate, Parent) GetNodesKey(Candidate, CandsKey); IF CandsKey<> KeyValue THEN Done:=FALSE ELSE IF EmptyTree(NodesLeftTree(Candidate)) THEN LinkParent(Candidate, NodesRightTree(Candidate), Parent, Tree) ELSE IF EmptyRight(NodesRightTree(Candidate)) THEN LinkParent(Candidate, NodesLeftTree(Candidate), Parent, Tree) ELSE GetNewCandidate(KeyValue, Candidate, Tree); KillTNode(Candidate); Done:= TRUE Cancellare il nodo 30 OldCandidate := Candidate Search(NodesRightTree(OldCandidate), KeyValue, Dummy, Candidate) OldCandidate^.Key := Candidate^.Key; CandsKey := Candidate^.Key; Search(NodesRightTree(OldCandidate), CandsKey, Dummy, Parent); IF Parent = NIL THEN LinkParent(Candidate,NodesRightTree(Candidate), OldCandidate, Tree) ELSE LinkParent(Candidate,NodesRightTree(Candidate), Parent, Tree) END; P30 P40 30 NIL P34 34 P40 34 P34 P P34 P35 P36 GetNewCandidate(KeyValue, Candidate, Tree); DeleteTNode(KeyValue, Tree, Done)

78 Programmazione Mod. B - Alberi - prof. E. Burattini cancella il nodo

79 Programmazione Mod. B - Alberi - prof. E. Burattini 79 Program AlberoProva(input,output); uses Crt, Alberi0; CONST NKey=-100; var Albero : BSTP; Item: KItemType; Chiave:KItemType; Info:InfoType; Done:boolean; {************** MAIN***********} begin clrscr; writeln('Costruiamo un Albero. '); BuildNameTree(Albero); WriteAlbero(Albero); Info:=33; writeln(' inserisci il nodo - per finire -100'); readln(chiave); WHILE Chiave<>NKey DO BEGIN AddTNode(Chiave,Info, Albero,Done); write(' aggiungi il nodo - per finire -100 >>> '); readln(chiave); END; WriteAlbero(Albero); readln; {cancella nodo} write(' cancella il nodo '); readln(chiave); DeleteTNode(Chiave, Albero,Done); IF DONE=FALSE THEN writeln(' il nodo', Chiave,' non è nell''albero'); WriteAlbero(Albero); readln; WriteAlbero(Albero); writeln; writeln(' FINE'); readln; end. albpr6

80 Programmazione Mod. B - Alberi - prof. E. Burattini 80 PROCEDURE StampaAlbero(Tree : BSTP; riga,inizio,fine:integer); var medio: integer; BEGIN if not(emptytree(tree)) then begin medio:=(inizio+fine) div 2; gotoxy(medio,riga); GetNodesKey(tree,Item); write(Item); StampaAlbero(NodesLeftTree(tree),riga+1,inizio,medio); StampaAlbero(NodesRightTree(tree),riga+1,medio,fine); END; PROCEDURE WriteAlbero(Tree:BSTP); PROCEDURE Wa(Tree:BSTP;I:integer); VAR J:integer; BEGIN IF NOT EmptyTree(Tree) THEN BEGIN Wa(NodesRightTree(Tree),I+1); FOR J:=1 TO I DO write(' '); write(Tree^.Key); writeln; Wa(NodesLeftTree(Tree),I+1); END; 1180

81 Programmazione Mod. B - Alberi - prof. E. Burattini 81 ALGORITMI DI ATTRAVERSAMENTO DI BST Algoritmi di attraversamento di un albero: LNR - (LeftNodeRight) - Attraversamento inorder Per ogni nodo 1 - Visita il sottoalbero sinistro 2 - Visita il nodo root 3 - Visita il sottoalbero destro NLR - (NodeLeftRight) - Attraversamento pre-order Per ogni nodo 1 - Visita il nodo root 2 - Visita il sottoalbero sinistro 3 - Visita il sottoalbero destro LRN - (LeftRightNode) - Attraversamento post-order Per ogni nodo 1 - Visita il sottoalbero sinistro 2 - Visita il sottoalbero destro 3 - Visita il nodo root

82 Programmazione Mod. B - Alberi - prof. E. Burattini 82 LNR - (LeftNodeRight) - Attraversamento ordinato Per ogni nodo 1 - Visita il sottoalbero sinistro 2 - Visita il nodo 3 - Visita il sottoalbero destro PROCEDURE Traverse(Root) IF root <> NIL THEN Traverse(Root^.Left){visita tutti i nodi del sottoalbero sinistro} Visit(Root) Traverse(Root^.Right) {visita tutti i nodi del sottoalbero destro} PROCEDURE ShowTree(NameTree: BSTType); VAR NodesKey: KItemType; BEGIN IF NOT EmptyTree(NameTree) THEN BEGIN ShowTree(NodesLeftTree(NameTree)); GetNodesKey(NameTree, Nome); writeln(Nome) ShowTree(NodesRightTree(NameTree)); END END;

83 Programmazione Mod. B - Alberi - prof. E. Burattini 83 PROCEDURE Traverse(Root) IF root <> NIL THEN Visit(Root) Traverse(Root^.Left){visita tutti i nodi del sottoalbero sinistro} Traverse(Root^.Right) {visita tutti i nodi del sottoalbero destro} NLR - (NodeLeftRight) - Attraversamento pre-ordinato Per ogni nodo 1 - Visita il nodo root 2 - Visita il sottoalbero sinistro 3 - Visita il sottoalbero destro PROCEDURE StampaAlbero(Tree : BSTP; riga,inizio,fine:integer); var medio: integer; BEGIN if not(emptytree(tree)) then begin medio:=(inizio+fine) div 2; gotoxy(medio,riga); GetNodesKey(tree,Item); write(Item); StampaAlbero(NodesLeftTree(tree),riga+1,inizio,medio); StampaAlbero(NodesRightTree(tree),riga+1,medio,fine); END

84 Programmazione Mod. B - Alberi - prof. E. Burattini 84 PROCEDURE Traverse(Root) IF root <> NIL THEN Traverse(Root^.Left){visita tutti i nodi del sottoalbero sinistro} Traverse(Root^.Right) {visita tutti i nodi del sottoalbero destro} Visit(Root) LRN - (LeftRightNode) - Attraversamento post-ordinato Per ogni nodo 1 - Visita il sottoalbero sinistro 2 - Visita il sottoalbero destro 3 - Visita il nodo root

85 85 Problema Eliminare un BST senza lasciare spazzatura. Soluzione Attraversa lalbero con un algoritmo LRN (post-order) e cancella ogni nodo incontrato. E utilizzato lLRN perché la root è sempre lultima ad essere deallocata dopo aver deallocato i nodi figli, e quindi nessun link è eliminato prima del dovuto. PROCEDURE KillTree(VAR Tree:BSTType); BEGIN IF NOT EmptyTree(Tree) THEN BEGIN KillTree(NodesLeftTree(Tree); KillTree(NodesRightTree(Tree); KillTNode(Tree) END END; Sergio Toni Anna Dora Giulio RiccardoGuido Maria Roberto

86 Programmazione Mod. B - Alberi - prof. E. Burattini 86 Problema Espressioni aritmetiche. Notazione Polacca Inversa 5 3 * / Visita LRN post-order Notazione Polacca Diretta / * Visita NLR pre-order / * Notazione infissa (5*3)/(4-1) Visita LNR inorder / * / * PROCEDURE Traverse(Root) IF root <> NIL THEN Visit(Root) Traverse(Root^.Left) Traverse(Root^.Right) PROCEDURE Traverse(Root) IF root <> NIL THEN Traverse(Root^.Left Traverse(Root^.Right) Visit(Root) PROCEDURE Traverse(Root) IF root <> NIL THEN Traverse(Root^.Left) Visit(Root) Traverse(Root^.Right)

87 Programmazione Mod. B - Alberi - prof. E. Burattini 87 Program AlberoConta(input,output); uses Alberi0; CONST NKey=-100; var Albero,Temp : BSTP; Item: KItemType; Chiave:KItemType; Info:InfoType; Done:boolean; Cont:integer; FUNCTION ContaNodiSinNul(Tree:BSTP):integer; VAR cont1:integer; BEGIN IF EmptyTree(Tree) THEN ContaNodiSinNul:= 0 else BEGIN IF NOT EmptyTree(NodesRightTree(Tree)) THEN ContaNodiSinNul:=ContaNodiSinNul(NodesRightTree(Tree)); IF NOT EmptyTree(NodesLeftTree(Tree)) THEN ContaNodiSinNul:=ContaNodiSinNul(NodesLeftTree(Tree)) ELSE ContaNodiSinNul:=ContaNodiSinNul(NodesRightTree(Tree))+1; END; {************** MAIN***********} begin writeln('Costruiamo un Albero. '); BuildNameTree(Albero); WriteAlbero(Albero); writeln('Ci sono ', ContaNodiSinNul(Albero),' nodi con sotto albero sinistro nullo'); end. ESERCIZIO { Dato un albero binario calcolare quanti nodi hanno il sottoalbero sinistro nullo.} ALBCONT2

88 Programmazione Mod. B - Alberi - prof. E. Burattini 88 { Scrivere un algoritmo che dato un albero binario scriva le chiavi in ordine prima crescente e poi decrescente } Program ScriviAlbero (input,output); uses Alberi0; CONST NKey=-100; var Albero : BSTP; Item, Chiave : KItemType; Info:InfoType; Done:boolean; PROCEDURE Crescente(Tree:BSTP); BEGIN IF Not EmptyTree(Tree) THEN BEGIN Crescente(NodesLeftTree(Tree)); write(' ',tree^.key); Crescente(NodesRightTree(Tree)); END; PROCEDURE DeCrescente(Tree:BSTP); BEGIN IF Not EmptyTree(Tree) THEN BEGIN DeCrescente(NodesRightTree(Tree)); write(' ',tree^.key); DeCrescente(NodesLeftTree(Tree)); END; {************** MAIN***********} begin writeln('Costruiamo un Albero. '); BuildNameTree(Albero); WriteAlbero(Albero); writeln('crescente '); Crescente(Albero); writeln('decrescente '); DeCrescente(Albero); end.

89 Programmazione Mod. B - Alberi - prof. E. Burattini 89 ESERCIZI 1- Scrivere una procedura che assegnato un albero binario di interi positivi non ordinato restituisca un puntatore al valore massimo e quante volte questo valore massimo è contenuto nell'albero. ES2GEN04 2- Scrivere una procedura che assegnato un albero binario di interi positivi non ordinato e due numeri positivi N1 e N2 restituisca la quantità di numeri pari compresi tra N1 e N2. ES2FEB04 3- Assegnato un albero non ordinato di interi scrivere una procedura ricorsiva che trasformi l'albero non ordinato in un albero BST. Determinare l'altezza dell'albero non ordinato e dell'albero BST. ESN0N0R2

90 Programmazione Mod. B - Alberi - prof. E. Burattini 90 uses Alberi0; CONST NKey=-100; VAR Albero: BSTP; Cont:integer; PROCEDURE ContaNodiNul(Tree:BSTP; VAR Conta:integer); BEGIN IF NOT EmptyTree(Tree) THEN BEGIN ContaNodiNul(NodesLeftTree(Tree),Conta); ContaNodiNul(NodesRightTree(Tree),Conta); IF (Tree^.Right=NIL) AND (Tree^.key MOD 2 <>0) THEN Conta:=Conta+1; END; {************** MAIN***********} BEGIN writeln('Costruiamo un Albero. '); BuildNameTree(Albero); WriteAlbero(Albero); cont:=0; ContaNodiNul(Albero,Cont); writeln(' Ci sono ',cont,' nodi con sotto albero destro nullo e padre dispari'); END. PROGRAM DispariNulli(input,output); { Assegnato un albero BST di numeri interi, fornire una procedura ricorsiva che dica quanti nodi, la cui chiave è un numero dispari, hanno sottoalbero destro nullo..}

91 Programmazione Mod. B - Alberi - prof. E. Burattini 91 ALBERO BILANCIATO CON M LIVELLI Totale Nodi N° NODI N° NODI 0 1 M Totale Nodi

92 Programmazione Mod. B - Alberi - prof. E. Burattini 92 ESERCIZIO { Dato un albero binario non bilanciato costruire un albero bilanciato.} Da Albero a Vettore Bilanciamento Stampa Non bilanciato bilanciato Controllo bilanciamento

93 Programmazione Mod. B - Alberi - prof. E. Burattini 93 Da Albero a Vettore Bilanciamento Stampa Non bilanciato bilanciato Controllo bilanciamento

94 Programmazione Mod. B - Alberi - prof. E. Burattini 94 FUNCTION UnisciAlberi(e:KItemType;a,b:BSTP) : BSTP; {crea un albero con chiave e e sottoalbero sinistro a e destro b eventualmente anche vuoti } VAR c:BSTP; BEGIN new(c); c^.left:=a; c^.right:=b; c^.key:=e; UnisciAlberi:=c; END; e x a y z b w

95 Programmazione Mod. B - Alberi - prof. E. Burattini 95 Program Bilanciare(input,output); uses Alberi0; CONST NKey=-100; TYPE Vettore=ARRAY[1..40] OF integer; var Albero,Bilanciato : BSTP; Item: KItemType; Chiave:KItemType; Info:InfoType; Done:boolean; V:vettore; I,Vmax:integer; FUNCTION vet2alb(vx:vettore;i,j:integer):BSTP; {a partire dal vettore V ordinato genero l'albero vet2alb} PROCEDURE DaAlberoAVettore(A:BSTP;VAR V:vettore;VAR max:integer); {Dato un albero BST costruisce un vettore ordinato} FUNCTION Bilancia(A:BSTP):integer; {Dato un albero controlla se è bilanciato, quasi-bilanciato o non bilancitao} PROCEDURE ControllaBilanciamento(A:BSTP); {************** MAIN***********} BEGIN writeln('Costruiamo un Albero. '); BuildNameTree(Albero); IF not ControlloBilanciamento(Albero) THEN BEGIN Vmax:=0; DaAlberoAVettore(Albero,V,Vmax); Bilanciato:=Vet2ALb(V,1,Vmax); writeln(ControlloBilanciamento(Bilanciato)); END ELSE writeln(' FINE'); END.

96 Programmazione Mod. B - Alberi - prof. E. Burattini 96 FUNCTION Bilancia(A:BSTP;VAR cmax,cmin:integer;livello:integer):integer; BEGIN IF not EmptyTree(A) THEN BEGIN IF EmptyTree(NodesRightTree(A)) OR EmptyTree(NodesLeftTree(A)) THEN BEGIN IF cmaxlivello THEN cmin:=livello; END; bilancia:=bilancia(NodesRightTree(A),cmax,cmin,livello+1); bilancia:=bilancia(NodesleftTree(A),cmax,cmin,livello+1); END; Bilancia:=cmax-cmin END; FUNCTION ControlloBilanciamento(A:BSTP):boolean; VAR cmx,cmn:integer; BEGIN cmx:=0;cmn:=maxint; IF Bilancia(A,cmx,cmn,0)=0 Then BEGIN ControlloBilanciamento:=TRUE;writeln(' L''albero è bilanciato') END ELSE IF Bilancia(A,cmx,cmn,0)=1 Then BEGIN ControlloBilanciamento :=TRUE;writeln(' L''albero è quasi bilanciato') END ELSE BEGIN ControlloBilanciamento:=FALSE;writeln(' L''albero non è bilanciato'); END;

97 Programmazione Mod. B - Alberi - prof. E. Burattini 97 PROCEDURE DaAlberoAVettore(A:BSTP;VAR V:vettore;VAR max:integer); VAR I:integer; BEGIN IF NOT EmptyTree(A) THEN BEGIN DaAlberoAVettore(NodesLeftTree(A),V,max); Max:=max+1; V[max]:=Tree^.key; DaAlberoAVettore(NodesRightTree(A),V,max); END; {************** MAIN***********} begin writeln('Costruiamo un Albero. '); BuildNameTree(Albero); WriteAlbero(Albero); ControllaBilanciamento(Albero); Vmax:=0; DaAlberoAVettore(Albero,V,Vmax); Bilanciato:=Vet2ALb(V,1,Vmax); ControllaBilanciamento(Bilanciato); writeln; writeln(' FINE'); readln; end.

98 Programmazione Mod. B - Alberi - prof. E. Burattini 98 FUNCTION vet2alb(vx:vettore;i,j:integer):BSTP; {a partire dal vettore V ordinato genero l'albero vet2alb} VAR K:integer; BEGIN IF I>J THEN Vet2alb:=NIL ELSE IF I=J THEN Vet2alb:=UnisciAlberi(Vx[I],NIL,NIL) ELSE BEGIN K:=(I+J) DIV 2; Vet2alb:=UnisciAlberi(Vx[K],vet2alb(Vx,I,K-1),vet2alb(vx,K+1,j)) END; {************** MAIN***********} begin writeln('Costruiamo un Albero. '); BuildNameTree(Albero); WriteAlbero(Albero); ControllaBilanciamento(Albero); Vmax:=0; DaAlberoAVettore(Albero,V,Vmax); Bilanciato:=Vet2ALb(V,1,Vmax); ControllaBilanciamento(Bilanciato); writeln(' FINE'); end. ALBBIL3 FUNCTION UnisciAlberi(e:KItemType;a,b:BSTP) : BSTP; {crea un albero con chiave e e sottoalbero sinistro a e destro b eventualmente anche vuoti } VAR c:BSTP; BEGIN new(c); c^.left:=a; c^.right:=b; c^.key:=e; UnisciAlberi:=c; END;

99 Programmazione Mod. B - Alberi - prof. E. Burattini 99 UnisciAlberi(Vx[K],vet2alb(Vx,I,K-1),vet2alb(vx,K+1,j)) gfedcba Vet2ALb(V,1,Vmax); Vet2ALb(V,1,7); K=4 UnisciAlberi(Vx[4],vet2alb(Vx,1,3),vet2alb(vx, 5,7)) Vet2ALb(V,1,3); K=2 UnisciAlberi(Vx[2],vet2alb(Vx,1,1),vet2alb(vx, 3,3)) Vet2ALb(V,1,1); K=1Vet2ALb(V,3,3); K=3 ac b UnisciAlberi(Vx[4],vet2alb(Vx,1,3),vet2alb(vx, 6,7)) Vet2ALb(V,5,7); K=6 Vet2ALb(V,5,5); K=5Vet2ALb(V,7,7); K=7 eg f d d f egca b

100 Programmazione Mod. B - Alberi - prof. E. Burattini 100 ESERCIZIO LA FAMIGLIA {calcola le parentele } Descritte le parentele secondo un albero non ordinato scrivere le funzioni FUNCTION Padre {dato un nome determinare se ha un padre e chi è} PROCEDURE Figlio {dato un nome determinare se ha uno o due figli e chi sono} FUNCTION Nonno {dato un nome determinare chi è il nonno} FUNCTION Fratello {dato un nome determinare se ha un fratello e chi è} FUNCTION Zio {dato un nome determinare se ha uno zio e chi è} END;

101 Programmazione Mod. B - Alberi - prof. E. Burattini 101 Esercizio. Dato un albero determinare quanti nonni hanno un solo nipote.

102 Programmazione Mod. B - Alberi - prof. E. Burattini 102


Scaricare ppt "Programmazione Mod. B - Alberi - prof. E. Burattini 1."

Presentazioni simili


Annunci Google