[Algo] Esercizio padri
Dato un albero T di n nodi rappresentato tramite il vettore dei padri P e un intero h, dare lo pseudocodice di un algoritmo che in tempo O(n) calcola il numero di nodi ad altezza h nell'albero T.
La mia idea.
Per prima cosa ricostruisco l'albero dal vettore dei padri e poi effettuo una visita modificata dell'albero in modo che mi ritorna il numero di nodi all'altezza h.
La procedura CreateTree ancora la devo elaborare.
Avrò una complessità della funzione Padri pari a O(n) ???
Ciao e buona serata
La mia idea.
Per prima cosa ricostruisco l'albero dal vettore dei padri e poi effettuo una visita modificata dell'albero in modo che mi ritorna il numero di nodi all'altezza h.
Padri( P:vettore dei padri, h: int ) -> numero di nodi ad altezza h
Nodo root = CreateTree(P) /* ritorna il nodo dell'albero creato dal vettore dei padri
int altezza = Vis( root , h ) /* ritorna il numero di nodi di altezza h
return altezza
Vis( T: nodo radice, h:int ) -> numero di nodi all'altezza h if T==NULL or h<=1 return 0 if k == 0 return 1 return Vis(T.left, h-- ) + Vis(T.right, k--)
La procedura CreateTree ancora la devo elaborare.
Avrò una complessità della funzione Padri pari a O(n) ???
Ciao e buona serata
Risposte
CreateTree consiste semplicemente nell'invertire le relazioni. Crei un array di nodi e poi scorri l'array dei padri e aggiungi il figlio nel nodo padre corrispondente. La complessità è certamente lineare.
Va bene la mia procedura di visita specifica per gli alberi binari?
Mi sta venendo un dubbio dato che la traccia non specifica che si tratta esclusivamente di alberi binari.
Mi sta venendo un dubbio dato che la traccia non specifica che si tratta esclusivamente di alberi binari.
No, la visita la devi fare per un generico albero.
Ciao, riprendo quest'esercizio dato che ho l'esame a breve e da allora non l'ho risolto.
Quindi una possibile strategia potrebbe essere la seguente:
- inizializzo una lista delle adiacenze pari a P.length;
- per ogni indice i in P, aggiungo nella lista delle adiacenze in P, il figlio i;
Così avrò la lista delle adiacenze del mio grafo diretto e aciclico, ovvero un abero e vi posso applicare una BFS per calcolare i nodi ad una certa altezza, dato che la BFS su un albero ha complessità al max O(|V|+|E|) dove |E| = |V|-1 in un albero. Quindi rientro in un O(n).
Però come capisco qual'è la radice dell'albero su cui cominciare la BFS??
Grazie e buona giornata
Quindi una possibile strategia potrebbe essere la seguente:
- inizializzo una lista delle adiacenze pari a P.length;
ListAdj(P.length)
- per ogni indice i in P, aggiungo nella lista delle adiacenze in P, il figlio i;
ListAdj[P[i]].add(i)
Così avrò la lista delle adiacenze del mio grafo diretto e aciclico, ovvero un abero e vi posso applicare una BFS per calcolare i nodi ad una certa altezza, dato che la BFS su un albero ha complessità al max O(|V|+|E|) dove |E| = |V|-1 in un albero. Quindi rientro in un O(n).
Però come capisco qual'è la radice dell'albero su cui cominciare la BFS??
Grazie e buona giornata
Ecco un possibile pseudocodice, vorrei avere vostri consigli.
La complessità dovrebbe essere O(n).
Padri( P: vettore dei padri, h: int ) -> ritorna il numero di nodi ad altezza h
ListAdj <- lista delle adiacenze di lunghezza pari a P.length
A <- array dei gradi entranti di ogni nodo inizializzato a 0 di lunghezza P.length
Dist <- array delle distanze di ogni nodo dalla radice
Nodo root <- inizializzato a null
int nodi <- 0
for nodo n in P then
if n != P[n] then
ListAdj[ P[n] ].add( n )
A[n] = A[n] + 1
int minDegree <- infinity
for nodo n in A then
if A[n] < minDegree then
minDegree <- A[n]
root <- n
Dist <- BFS(root)
for nodo n in Dist then
if Dist[n] == h then
nodi <- nodi +1
return n
La complessità dovrebbe essere O(n).