Visite di alberi binari Laboratorio di Algoritmi e Strutture Dati
Visita di Alberi Gli alberi possono essere visitati (o attraversati) in diversi modi: Visita in Preordine: prima si visita il nodo e poi i suoi sottoalberi; Visita Inordine (se binario): prima si visita il sottoalbero sinistro, poi il nodo e infine il sottoalbero destro; Visita in Postordine : prima si visitano i sottoalberi, poi il nodo.
Visita di Alberi Binari: in profondità preordine Visita-Preordine(T) IF T NIL THEN vista T Visita-Preordine(T->sx) Visita-Preordine(T->dx) sx node key dx T a b e c d f g Sequenza: a b c d e f g
Visita di Alberi Binari: in profondità preordine Visita-Preordine(node *T) { IF (T) { Vista(T); Visita-Preordine(T->sx); Visita-Preordine(T->dx); T b a e c d f g sx node key dx Sequenza: a b c d e f g
Visita di Alberi Binari: in profondità inordine Visita-Inordine(T) IF T NIL THEN Visita-Inordine(T->sx) vista T Visita-Inordine(T->dx) T a b e c d f g Sequenza: c b d a f e g
Visita di Alberi Binari: in profondità postordine Visita-Postordine(T) IF T NIL THEN Visita-Postordine(T->sx) Visita-Postordine(T->dx) vista T T a b e c d f g Sequenza: c d b f g e a
Visita Preorder Iterativa Visita-preorder-iter(T) stack = NIL curr = T WHILE (stack NIL OR curr NIL) DO IF (curr NULL) THEN /* Discesa sx */ vista curr push(stack,curr) next = curr->sx ELSE /* Discesa dx */ curr = top(stack) pop(stack) next = curr->dx curr = next
Visita-preorder-iter(node * T) { stack *st = NULL; node *curr = T, next; while(st curr) { if(curr) { /* Visita e discesa a sx */ Visita(curr); st = push(st,curr); next = curr->sx else { /* Discesa a dx */ curr = top(st); st = pop(st); next = curr->dx; curr = next;
Visita-preorder-iter2(node * T) { stack *st = NULL; node *curr = T, next; while(curr) { Visita(curr); if(curr->dx) /* Salva per discesa a dx */ st = push(st,curr->dx); if (curr->sx) /* Discesa a sx */ next = curr->sx else { /* Discesa a dx */ if (st) { next = top(st); st = pop(st); else next = NULL; curr = next
Visita Inorder Iterativa Visita-inorder-iter(T) stack = NIL curr = T WHILE (stack NIL OR curr NIL) DO IF (curr NULL) THEN /* Discesa sx */ push(stack,curr) next = curr->sx ELSE /* Discesa dx */ curr = top(stack) pop(stack) vista curr next = curr->dx curr = next
Visita-inorder-iter(node * T) { stack *st = NULL; node *curr = T, next; while(st curr) { if(curr) { /* Discesa a sx */ st = push(st,curr); next = curr->sx else { /* Visita e discesa a dx */ curr = top(st); st = pop(st); Visita(curr); next = curr->dx; curr = next
Visita-inorder-iter2(node *T) { stack *st = NULL; node *curr, *last = NULL; if (T) st = push(t); while (st) { /* Discesa lungo l albero corrente */ curr = top(st); if (!last curr == last->sx curr == last->dx) { if (curr->sx) st = push(st,curr->sx); else { Visita(curr); st = pop(st); if (curr->dx) st = push(st,curr->dx); else if (last == curr->sx){ /* Risalita da sinistra */ Visita(curr); if (curr->dx) st = push(st,curr->dx); else if (last == curr->dx) st = pop(st); /* Risalita da destra */ last = curr;
Visita Postorder Iterativa Visita-postorder-iter(T) stack = NIL curr = T, last = NIL, next=nil WHILE (stack NIL OR curr NIL) DO IF (curr NIL) THEN /* Discesa sx */ push(stack,curr) next = curr->sx ELSE curr = top(stack) /* Risalita */ IF (curr->dx = NIL OR last = curr->dx) THEN vista curr pop(stack) next = NIL ELSE next = curr->dx /* Discesa dx */ last = curr curr = next
Visita-postorder-iter(node * T) { stack *st = NULL; node *last, curr = T, next; while(st curr) { if(curr) { /* Discesa a sx */ st = push(st,curr); next = curr->sx else { /* Visita o discesa a dx */ curr = top(st); if (!curr->dx last == curr->dx){ Visita(curr); st = pop(st); next = NULL; else curr = curr->dx; /* Discesa a dx */ last = curr; curr = next;
Visita-postorder-iter2(node *T) { stack *st = NULL; node *curr, *last = NULL; if (T) st = push(t); while (st) { /* Discesa lungo l albero corrente */ curr = top(st); if (!last curr == last->sx curr == last->dx) { if (curr->sx) st = push(st,curr->sx); else if (curr->dx) st = push(st,curr->dx); else { Visita(curr); st = pop(st); else if (last == curr->sx){ /* Risalita da sinistra */ if (curr->dx) st = push(st,curr->dx); else { Visita(curr); st = pop(st); else if (last == curr->dx){ /* Risalita da destra */ Visita(curr); st = pop(st); last = curr;
DUPLICA (T) nodo *n = NIL IF (T!= NIL) THEN n = alloca_nodo(t->key) n->sx = DUPLICA(T->sx) n->dx = DUPLICA(T->dx) return n;
DUPLICA_ITER(T) c = T WHILE (st1!= NIL OR c!= NIL) DO IF (c!= NIL) THEN // fase di discesa n = alloca_nodo(c->key) // crea nodo per la copia st1 = push(st1,c); st2 = push(st2,n) // memorizza c e n in stack nxt = c->sx ; ret = NIL; // scende a sinistra nell originale ELSE // fase di risalita da dx o da sx nell originale c = top(st1); n = top(st2) // recupera c e n da stack IF (c->dx = NIL lst = c->dx) THEN // se risale da destra IF (c->dx = NIL) THEN n->sx = ret // attacca ret come figlio sinistro di n ELSE n->dx = ret // attacca ret come figlio destro di n st1 = pop(st1); st2 = pop(st2) ret = n; nxt = NIL // risale tenendo traccia del last per la copia ELSE // se risale da sx n->sx = ret // attacca ret come figlio sinistro di n nx = c->dx // scende a destra se necessario ret = NIL // ret viene resettato a NIL lst = c; c = nxt // effettua l aggiornamento di curr e last per l originale return n