Alberi binari di ricerca Laboratorio di Algoritmi e Strutture Dati Ingegneria e Scienze Informatiche - Cesena A.A. 2013-2014 Pietro Di Lena [email protected], [email protected] Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Alberi binari di ricerca Operazioni basilari su alberi binari di ricerca Ricerca: cerca un nodo con una certa chiave Minimo: cerca il nodo con la chiave più piccola in un sottoalbero Massimo: cerca il nodo con la chiave più grande in un sottoalbero 8 5 18 7 15 9 17 16 Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Alberi binari di ricerca Operazioni basilari su alberi binari di ricerca Ricerca: cerca un nodo con una certa chiave Minimo: cerca il nodo con la chiave più piccola in un sottoalbero Massimo: cerca il nodo con la chiave più grande in un sottoalbero 8 5 Nodo con chiave 18 18 Nodo con chiave 6 NULL 7 15 9 17 16 Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Alberi binari di ricerca Operazioni basilari su alberi binari di ricerca Ricerca: cerca un nodo con una certa chiave Minimo: cerca il nodo con la chiave più piccola in un sottoalbero Massimo: cerca il nodo con la chiave più grande in un sottoalbero Minimo assoluto 8 5 18 Minimo nel sottoalbero con chiave 18 7 15 9 17 16 Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Alberi binari di ricerca Operazioni basilari su alberi binari di ricerca Ricerca: cerca un nodo con una certa chiave Minimo: cerca il nodo con la chiave più piccola in un sottoalbero Massimo: cerca il nodo con la chiave più grande in un sottoalbero Massimo assoluto 8 5 Massimo nel sottoalbero con chiave 18 7 18 15 9 17 16 Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Alberi binari di ricerca Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Operazioni basilari su alberi binari di ricerca: pseudocodice 1: function Search(T , key ) 2: if T=NULL then 3: return NULL 4: else if Key(T )=key then 5: return T 6: else if key < Key(T) then 7: return Search(Left(T ), key ) 8: else 9: return Search(Right(T ), key ) 10: end if 11: end function 1: function SearchMin(T ) 2: if T=NULL then 3: return NULL 4: else if Left(T )=NULL then 5: return T 6: else 7: return SearchMin(Left(T )) 8: end if 9: end function 1: function SearchMax(T ) 2: if T=NULL then 3: return NULL 4: else if Right(T )=NULL then 5: return T 6: else 7: return SearchMax(Right(T )) 8: end if 9: end function Quanto costano queste operazioni? Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Alberi binari di ricerca Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Operazioni basilari su alberi binari di ricerca: pseudocodice 1: function Search(T , key ) 2: if T=NULL then 3: return NULL 4: else if Key(T )=key then 5: return T 6: else if key < Key(T) then 7: return Search(Left(T ), key ) 8: else 9: return Search(Right(T ), key ) 10: end if 11: end function 1: function SearchMin(T ) 2: if T=NULL then 3: return NULL 4: else if Left(T )=NULL then 5: return T 6: else 7: return SearchMin(Left(T )) 8: end if 9: end function 1: function SearchMax(T ) 2: if T=NULL then 3: return NULL 4: else if Right(T )=NULL then 5: return T 6: else 7: return SearchMax(Right(T )) 8: end if 9: end function Quanto costano queste operazioni? Risposta O(height(T )) Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Alberi binari di ricerca Predecessore e successore di un nodo Predecessore: cerca il predecessore di un dato nodo Successore: cerca il successore di un dato nodo 8 5 18 7 15 9 17 16 Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Alberi binari di ricerca Predecessore e successore di un nodo Predecessore: cerca il predecessore di un dato nodo. Due casi possibili: 1 2 Il nodo ha un figlio sinistro ⇒ il predecessore è il massimo nel sottoalbero sinistro. Il massimo non ha un figlio destro. Il nodo non ha un figlio sinistro ⇒ il predecessore è l’antenato più vicino che contiene il nodo in questione nel suo sottoalbero destro (non esiste se e solo se il nodo è il minimo assoluto). Successore: cerca il successore di un dato nodo 8 5 18 7 15 Predecessore di 18 9 17 16 Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Alberi binari di ricerca Predecessore e successore di un nodo Predecessore: cerca il predecessore di un dato nodo. Due casi possibili: 1 2 Il nodo ha un figlio sinistro ⇒ il predecessore è il massimo nel sottoalbero sinistro. Il massimo non ha un figlio destro. Il nodo non ha un figlio sinistro ⇒ il predecessore è l’antenato più vicino che contiene il nodo in questione nel suo sottoalbero destro (non esiste se e solo se il nodo è il minimo assoluto). Successore: cerca il successore di un dato nodo 8 5 Predecessore di 5 Predecessore di 9 NULL 7 18 15 9 17 16 Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Alberi binari di ricerca Predecessore e successore di un nodo Predecessore: cerca il predecessore di un dato nodo. Due casi possibili: 1 Il nodo ha un figlio sinistro ⇒ il predecessore è il massimo nel sottoalbero sinistro. 2 Il nodo non ha un figlio sinistro ⇒ il predecessore è l’antenato più vicino che contiene il nodo in questione nel suo sottoalbero destro (non esiste se e solo se il nodo è il minimo assoluto). Successore: cerca il successore di un dato nodo. Due casi possibili: 1 Il nodo ha un figlio destro ⇒ il successore è il minimo nel sottoalbero destro. Il minimo non ha un figlio sinistro. 2 Il nodo non ha un figlio destro ⇒ il successore è l’antenato più vicino che contiene il nodo in questione nel suo sottoalbero sinistro (non esiste se e solo se il nodo è il massimo assoluto). 8 5 18 Successore di 8 7 15 9 17 16 Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Alberi binari di ricerca Predecessore e successore di un nodo Predecessore: cerca il predecessore di un dato nodo. Due casi possibili: 1 Il nodo ha un figlio sinistro ⇒ il predecessore è il massimo nel sottoalbero sinistro. 2 Il nodo non ha un figlio sinistro ⇒ il predecessore è l’antenato più vicino che contiene il nodo in questione nel suo sottoalbero destro (non esiste se e solo se il nodo è il minimo assoluto). Successore: cerca il successore di un dato nodo. Due casi possibili: 1 Il nodo ha un figlio destro ⇒ il successore è il minimo nel sottoalbero destro. Il minimo non ha un figlio sinistro. 2 Il nodo non ha un figlio destro ⇒ il successore è l’antenato più vicino che contiene il nodo in questione nel suo sottoalbero sinistro (non esiste se e solo se il nodo è il massimo assoluto). 8 5 Successore di 18 Successore di 7 NULL 7 18 15 9 17 16 Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Alberi binari di ricerca Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Predecessore e successore di un nodo Per semplificare l’implementazione delle funzioni predecessore e successore abbiamo la necessità di modificare la struttura dati nodo. E’ necessario introdurre un nuovo puntatore che permetta di accedere velocemente al padre di un nodo. Le procedure InsKey(T , key ) deve essere modificate in modo da tener conto di questo nuovo puntatoreLe funzioni DeleteTree(T ),Search(T , key ), SearchMin(T ), SearchMax(T ) non necessitano di modifiche. Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Alberi binari di ricerca Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Nota: definizione della struttura dati nodo in c con puntatore al padre # include < stdlib .c > typedef struct NODE { int key ; struct NODE * left ; struct NODE * right ; struct NODE * up ; } NODE ; NODE * NodeAlloc ( int key ) { NODE * node = ( NODE *) malloc ( sizeof ( NODE ) ) ; node - > key node - > left node - > right node - > up = = = = key ; NULL ; NULL ; NULL ; return node ; } Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Alberi binari di ricerca Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Predecessore e successore di un nodo: pseudocodice Pseudocodice della funzione che cerca il successore di un nodo. Implementare la funzione (simmetrica) per cercare il predecessore. 1: function SearchSuccessor(T ) 2: if T = NULL then 3: return NULL 4: else 5: if Right(T ) 6= NULL then 6: return SearchMin(Right(T )) 7: else 8: x ←T 9: y ← UP(x) 10: while y 6= NULL and x = Right(y ) do 11: x ←y 12: y ← UP(x) 13: end while 14: return y 15: end if 16: end if 17: end function Quanto costa cercare il successore o predecessore di un nodo? Quanto costa cercare il successore o predecessore di un nodo senza puntatore al padre? Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Alberi binari di ricerca Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Procedura di inserimento aggiornata 1: procedure InsKey(T , key ) 2: if key < Key(T) then 3: if Left(T ) = NULL then 4: Left(T )←NodeAlloc(key ) 5: Up(Left(T ))← T 6: else 7: InsKey(Left(T ), key ) 8: end if 9: else if key > Key(T) then 10: if Right(T ) = NULL then 11: Right(T )←NodeAlloc(key ) 12: Up(Right(T ))← T 13: else 14: InsKey(Right(T ), key ) 15: end if 16: end if 17: end procedure Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Alberi binari di ricerca Cancellazione di un nodo: esempio Vogliamo rimuovere un nodo dall’albero, mantenendo le proprietà di un albero binario di ricerca. Tre casi possibili: 1 Il nodo da rimuovere è una foglia 2 Il nodo da rimuovere ha un solo figlio 3 Il nodo da rimuovere ha due figli 8 5 18 7 15 9 17 16 Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Alberi binari di ricerca Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Cancellazione di un nodo: esempio Vogliamo rimuovere un nodo dall’albero, mantenendo le proprietà di un albero binario di ricerca. Tre casi possibili: 1 Il nodo da rimuovere è una foglia ⇒ rimuoviamo il nodo. 2 Il nodo da rimuovere ha un solo figlio 3 Il nodo da rimuovere ha due figli 8 8 5 18 7 5 15 18 7 15 Foglia 9 17 17 16 Pietro Di Lena 16 Laboratorio di Algoritmi e Strutture Dati Alberi binari di ricerca Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Cancellazione di un nodo: esempio Vogliamo rimuovere un nodo dall’albero, mantenendo le proprietà di un albero binario di ricerca. Tre casi possibili: 1 Il nodo da rimuovere è una foglia ⇒ rimuoviamo il nodo. 2 Il nodo da rimuovere ha un solo figlio ⇒ rimuoviamo il nodo e lo sostituiamo col figlio. 3 Il nodo da rimuovere ha due figli 8 8 5 18 5 18 Ha un solo figlio 7 15 7 17 17 16 16 Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Alberi binari di ricerca Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Cancellazione di un nodo: esempio Vogliamo rimuovere un nodo dall’albero, mantenendo le proprietà di un albero binario di ricerca. Tre casi possibili: 1 Il nodo da rimuovere è una foglia ⇒ rimuoviamo il nodo. 2 Il nodo da rimuovere ha un solo figlio ⇒ rimuoviamo il nodo e lo sostituiamo col figlio. 3 Il nodo da rimuovere ha due figli ⇒ sostituiamo la chiave del nodo con la chiave del suo successore e rimuoviamo il successore. Per ipotesi, il successore esiste nel sottoalbero a destra. La rimozione del successore ricade sempre nel caso 1 o 2. Ha due figli 8 16 5 18 7 Successore di 8 17 5 18 7 17 16 Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Alberi binari di ricerca Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Cancellazione di un nodo: pseudocodice 1: procedure DelNode(T ) 2: if IsLeaf(T ) then 3: if IsLeftChild(T ) then 4: Left(Up(T ))← NULL 5: else if IsRightChild(T ) then 6: Right(Up(T ))← NULL 7: end if 8: Delete(T ) 9: else if HasOneChild(T ) then 10: x ← Child(T ) 11: if IsLeftChild(T ) then 12: Left(Up(T ))← x 13: else if IsRightChild(T ) then 14: Right(Up(T ))← x 15: end if 16: Up(x) ← Up(T ) 17: Delete(T ) 18: else if HasTwoChildren(T ) then 19: x ← SearchSuccessor(T ) 20: Key(T ) ← Key(x) 21: DelNode(x) 22: end if 23: end procedure 1: procedure DelKey(T , key ) 2: x ← Search(T , key ) 3: if x 6= NULL then 4: DelNode(x) 5: end if 6: end procedure Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati Alberi binari di ricerca Operazioni basilari su alberi binari di ricerca Operazioni basilari su alberi binari di ricerca: pseudocodice Predecessore e successore di un nodo Predecessore e successore di un nodo: pseudocodice Cancellazione di un nodo Cancellazione di un nodo: pseudocodice Nota: definizione di macro # define # define # define # define Up ( n ) Left ( n ) Right ( n ) Key ( n ) (( n ) -> up ) (( n ) -> left ) (( n ) -> right ) (( n ) -> key ) # define IsLeftChild ( n ) ((( n ) != NULL && Up ( n ) != NULL \\ && Left ( Up ( n ) ) == n ) ?1:0) # define IsRightChild ( n ) ((( n ) != NULL && Up ( n ) != NULL \\ && Right ( Up ( n ) ) == n ) ?1:0) # define IsLeaf ( n ) ((( n ) != NULL && Left ( n ) == NULL \\ && Right ( n ) == NULL ) ?1:0) # define HasTwoChild ren ( n ) ((( n ) != NULL && Left ( n ) != NULL \\ && Right ( n ) != NULL ) ?1:0) # define HasOneChild ( n ) (( n ) != NULL && ! IsLeaf ( n ) \\ && ! HasTwoCh ildren ( n ) ) # define Child ( n ) (( n ) == NULL ? NULL : \\ ( Left ( n ) != NULL ? Left ( n ) : Right ( n ) ) ) Pietro Di Lena Laboratorio di Algoritmi e Strutture Dati