1 / 79

CAPITOLO 18

CAPITOLO 18. ESERCIZIO Date le seguenti definizioni TYPE nodoint=^tipoint tipoint=RECORD numero:integer; link:nodoint; END; ListaInt:Nodoint; Siano date 2 liste una Lint :ListaInt e una Lchar :ListaChar . Sia data la funzione trovato(Lchar,intero):char

brice
Download Presentation

CAPITOLO 18

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CAPITOLO 18

  2. ESERCIZIO Date le seguenti definizioni TYPE nodoint=^tipoint tipoint=RECORD numero:integer; link:nodoint; END; ListaInt:Nodoint; Siano date 2 liste una Lint:ListaInt e una Lchar:ListaChar . Sia data la funzione trovato(Lchar,intero):char e la procedura sostituisci(intero,Lint,trovato) Scrivere un algoritmo che sostituisca ogni elemento della lista Lint con il codice ASCII del carattere trovato in Lchar nella posizione determinata dal valore dell’elemento in Lint. Esempio Input: Lint: 5  4  3 Lchar: a  f  g  h  m Output Lint 109  104  103 Nota: La funzione Trovato restituisce il carattere ‘0’ nel caso in cui il valore intero supera la lunghezza di Lchar. Tale carattere può essere sostituito all’intero. nodochar=^tipochar tipochar=RECORD carattere:char; link:nodochar; END; ListaChar:=Nodochar;

  3. 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.

  4. ALBERI BINARI • Un albero è binario se ogni nodo è al più collegato ad altri due • Un albero binario è: • L’albero vuoto • oppure è costituito da una radice e da un sottoalbero sinistro ed un sottoalbero destro • L’albero è dunque una struttura ricorsiva non lineare. • I suoi elementi sono detti nodi

  5. I due disegni rappresentano due alberi uguali ma due alberi binari diversi. L’ovvio modo di rappresentare un albero consiste nell’assegnare ad ogni nodo due puntatori uno che punta al sottoalbero sinistro ed uno che punta al sottoalbero destro.

  6. Radice (root) Albero Binario Sotto albero Per gestire gli alberi introduciamo un ADT costituito da nodi non più con uno ma con due campi per i puntatori. Attraverso questa struttura potremo rappresentare gli alberi di ricerca binari.

  7. Ugo Carlo Maria Peppe Nicola Giulio Emma Guido Carla Anna Angela

  8. XXX Tree Left Structure Right Structure 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. Un albero (sotto albero), che punta a NIL e cioè non contiene nodi è detto albero (sotto albero) vuoto.

  9. Livello del nodo X = 3 Sotto albero Nodi fratelli Genitore X Figlio Foglie Altezza dell’albero= Massimo numero di livelli H=3 Radice (root) Albero Binario Cammino (path)

  10. 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).

  11. 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 Sergio Toni Luigi Ugo Campo chiave Key Field Left Right Maria Giulio Dora Guido Riccardo Anna Roberto

  12. TNode Left Key Info Right 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;

  13. TNode Left Key Info Right • 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 • seleziona il figlio a sinistra di un dato nodo • seleziona il figlio a destra di un dato nodo

  14. Left Key Info Right TNode 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 Node:LNodeP); {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;

  15. Left Key Info Right TNode 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 } 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;

  16. Left Key Info Right 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; 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;

  17. Left Key Info Right 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; PROCEDURE KillTNode(VAR Node:LNodeP); {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;

  18. Left Key Info Right 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; 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;

  19. Left Key Info Right 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; 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;

  20. Left Key Info Right 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; 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:

  21. Left Key Info Right 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; 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:

  22. 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

  23. Toni Ugo Maria Maria Ugo Riccardo Le stesse informazioni possono essere contenute in alberi binari di forma diversa. Guido Anna Dora Dora Giulio Guido Anna Giulio Sergio Luigi Riccardo Sergio Luigi Toni

  24. H=3 L=3 H=3 L=2 L=3 Foglie Un albero si dice bilanciato se il livello di tutte le foglie è uguale all’altezza dell’albero o a questa stessa altezza meno 1.

  25. H=5 L=2 L=3 Foglie L=4 L=5

  26. E’ evidente che un albero bilanciato si esplora per fare una ricerca in un numero di passi inferiore a quello necessario per esplorare un albero non bilanciato. Se un albero bilanciato ha M livelli, il numero di nodi di cui è formato può variare tra 2M e 2(M+1) -1. In un albero bilanciato il tempo massimo di ricerca è di O(log2 (N)) dove N è il numero di nodi.

  27. 0 N° NODI N° NODI 1 M Totale Nodi Totale Nodi ALBERO BILANCIATO CON 3 LIVELLI

  28. NODI N° NODI 0 1 M Totale Nodi Totale Nodi ALBERO BILANCIATO CON 3 LIVELLI

  29. Serie geometrica

  30. Supponiamo sia assegnata una lista di N oggetti tra i quali esiste una relazione d’ordine. 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(log2(N)). Se questo non avviene il caso peggiore in cui possiamo trovarci è pari a O(N). Maria Toni Ugo Anna Dora Giulio Guido Luigi Riccardo Sergio 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.39* O(log2(N)).

  31. Sergio Toni Left Key Info Right 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; 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. Maria Giulio Dora Guido Riccardo Anna Roberto

  32. Left Key Info Right 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; FUNCTION LeftMost(Root: BSTP): BSTP; Definizione della funzione VAR NodoEsaminato:BSTP; Definizione delle variabili BEGIN IF EmptyTree(Root) THEN NodoEsaminato = NIL; ELSE NodoEsaminato = Root; Verifica se l’albero è vuoto WHILE NodesLeftTree(NodoEsaminato) <> NIL DO NodoEsaminato = NodesLeftTree(NodoEsaminato) ; LeftMost: = NodoEsaminato END: Cerca il nodo

  33. OPERAZIONI SUI BST Left Key Info Right 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; BSTType=BSTP VAR NomeAlbero:BSTType Ogni nodo di un BST punta ad altri due nodi, ciascuno dei quali può essere visto come 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. Quindi 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)

  34. INTERFACE PROCEDURE MakeTree(VAR Tree: BSTType); {inizializza a NIL l’albero, creando un albero vuoto} PROCEDURE AddTNode(KeyValue:KItemType; TheInfo:InfoType;VAR Tree: BSTType; VAR Done:boolean); {aggiunge un nodo all’albero rispettando la struttura di un BST, se il KeyValue è già presente nell’albero 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 l’albero è vuoto}

  35. Left Key Info Right TNode ESEMPIO: COSTRUZIONE DI UN BST DI NOMI 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;

  36. Maria Giulio Sergio Dora Guido Riccardo Toni Anna Roberto COSTRUZIONE DI UN BST DI NOMI Supponiamo che vengano introdotti da tastiera i seguenti nomi: Maria Giulio Sergio Dora Guido Riccardo Toni Anna Roberto return

  37. 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

  38. 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(‘ L’albero è stato piantato’); END; 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;

  39. Maria Giulio Sergio Dora Guido Riccardo Toni Anna Roberto 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 alfabetico. Anna Dora Giulio Guido Maria Riccardo Roberto Sergio Toni

  40. Sergio Toni Maria Giulio Dora Guido Riccardo Anna Roberto MOSTRA IL CONTENUTO DI UN BST Pseudo codice 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 ShowTree(NodesLeftTree(NameTree)); GetNodesKey(NameTree, Nome); Writeln(Nome) ShowTree(NodesRightTree(NameTree));

  41. La procedura ShowTree(NameTree) è una procedura ricorsiva il cui case base è rappresentato dall’albero vuoto (EmptyTree). In altre parole il processo di pop inizia non appena l’argomento 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;

  42. IMPLEMENTATION PROCEDURE MakeTree(VAR Tree: BSTType); {inizializza a NIL l’albero, creando un albero vuoto} BEGIN Tree:=NIL END; FUNCTION EmptyTree(Tree: BSTType): boolean; {ritorna vero se l’albero è vuoto} BEGIN EmptyTree:=Tree=NIL END;

  43. Sergio Toni Maria Giulio Dora Guido Riccardo Anna Roberto RICERCA DI UN DATO SU UN BST Riccardo ?????????

  44. 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<MatrCercata THEN Binary := Binary(Studenti, MatrCercata, Mid+1, Hi) ELSE Binary := Binary(Studenti, MatrCercata, Lo, Mid-1) END; END; CASE BASE 1 CASE BASE 2 ESPRESSIONE RICORSIVA

  45. Pseudo codice FUNCTION SearchTNode(Tree; KeyValue); BSTP IF EmptyTree(Tree) THEN SearchTNode  NIL ELSE GetNodesKey(Tree, TheKey) IF TheKey = KeyValue THEN SearchTNode  Tree ELSE IF KeyValue < TheKey SearchTNode  SearchTNode(NodesLeftTree(Tree), KeyValue) ELSE SearchTNode  SearchTNode(NodesRightTree(Tree), KeyValue)

  46. 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;

  47. A B C D E F G H ESERCIZIO Sia assegnato un albero binario. scrivere un algoritmo tale che sposti ogni figlio sinistro nel corrispondente figlio destro e viceversa. A C B F E D H G

  48. Toni Sergio Maria Giulio Dora Guido Riccardo Roberto Anna Rolando AGGIUNTA DI UN DATO SU UN BST Per aggiungere un nodo a un BST è necessario innanzitutto verificare che l’Item non esiste già, perché in tal caso il nodo non viene aggiunto. Se non esiste bisogna trovare la sua corretta posizione nell’albero, cioè il suo genitore e attribuirgli come figli, sinistro e destro il puntatore NIL.

  49. PROCEDURE AddTNode(KeyValue:KItemType; TheInfo:InfoType;VAR Tree: BSTType; VAR Done:boolean); {aggiunge una foglia all’albero rispettando la struttura di un BST, se il KeyValue è già presente nell’albero 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}

  50. Se il nodo che vogliamo inserire, avente un certo KeyValue, esiste, allora Tnode non è vuoto e quindi non lo aggiungiamo altrimenti lo aggiungiamo 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

More Related