Dato un albero determinarne la larghezza

di il
4 risposte

Dato un albero determinarne la larghezza

La larghezza di un albero è definita come il numero massimo di nodi che stanno tutti al medesimo
livello.
Salve a tutti non riesco a completare questo esercizio, quel che ho fatto è costruire una classe albero e poi fare una BFS in modo da visitare i nodi per livelli, tuttavia mi so inceppato e non riesco a determinare i nodi che appartengono ad ogni livello : il codice che ho usato per fare BFS è


 public Queue<Node> BFS(Node root) 
    {
    	
    	Queue<Node> listaDati= new Queue();
        if (root== null)
            return null;
        Queue<Node> queue= new Queue<Node>();
        queue.enqueue(root);
       while(!queue.isEmpty()) {
        Node t = queue.dequeue();
         listaDati.enqueue(t);  
                   if (t.left != null)   queue.enqueue(t.left); 
  		  if (t.right!= null)  queue.enqueue(t.right); 
  		}
        
		return listaDati;
        
    }
  
la classe Node è banale e contiene un intero che rappresenta in valore del nodo e due riferimenti ai nodi destro e sinistro.
a questo punto volevo crearmi un vettore che contenesse un certo numero di interi pari al numero di nodi ed in particolare i nodi dello stesso livello siano identificati dallo stesso numero(1 identifica i nodi del primo livello, 2 del secondo e cosi via) quindi vedo quale intero fra tutti si ripete più volte e quella è la larghezza massima. come detto non riesco a identificare i nodi a quale livello appartengono. spero mi riusciate ad indirizzare..grazie in anticipo

4 Risposte

  • Re: Dato un albero determinarne la larghezza

    Ciao Enrico92,
    per risolvere il tuo problema ti consiglio di introdurre una variabile altezza nella tua classe Node. Questa variabile è semplicemente inizializzata all'altezza del nodo padre + 1 . Chiaramente ti sarà sufficiente dichiarare che la root è al livello 0, ed il gioco è fatto (se non lo hai già implementato ti sarà necessario che ogni nodo abbia il riferimento del nodo padre solo la root avrà parentNode = null).

    Una volta che puoi recuperare l'altezza di ogni nodo costruire quel vettore diventa estremamente facile.
  • Re: Dato un albero determinarne la larghezza

    Quindi in questo modo non ho più bisogno della bfs giusto?
  • Re: Dato un albero determinarne la larghezza

    Scusa se rispondo solo ora.
    Per rispondere subito alla tua domanda, no, non serve, anche se ti consiglio di non cancellare il metodo perchè può essere utile per altre cose, tuttavia se mi consenti c'è un metodo più pratico per fare quello vuoi e la bfs può servire.

    Allora tecnicamente parlando in termini di costi computazionali, costruire quel vettore ha un costo per essere creato di n elementi + il costo per per trovare quale livello compare maggiormente (sempre proporzionale ad n). Ora io non so quale tipi di alberi tu debba creare ma se sono molto grandi, quindi con molti nodi, questo metodo diventa poco efficiente. Per migliorare il vettore ti consiglio di usare una funzione hash molto semplice.
    Il vettore lo crei di dimensione h dove h è l'altezza dell'albero (la massima resa di questo metodo è quando l'albero è completo o almeno bilanciato, la peggiore invece uguaglia i costi del metodo che proponevi tu)
    l'indice i del vettore corrisponde al livello dell'albero e il suo contenuto la quantità di nodi che vi fanno parte. Per popolare tale vettore hai due possibilità:
    1) Utilizzando il concetto di costo ammortizzato, potresti, all'inserimento di un nuovo nodo nell'albero, aggiornare il vettore dando un +1 all'i-esimo elemento che corrisponde al livello di quel nodo (avendo così un vettore sempre aggiornato e pronto a darti il risultato che vuoi) (ricordati che però dovresti detrarre 1 qualora togliessi un nodo dall'albero)

    2)applicare la visita bfs (o qualunque tipo ti visita tu voglia che controlli ogni nodo), vedere a quale livello appartiene il nodo ed incrementare l'i-esimo elemento del vettore di 1.
    A conti fatti avrai un vettore contenente quanti nodi appartengono a ciascun livello quindi trovando il massimo hai la tua risposta.

    Ora mi sto lasciando andare, ma se volessi renderlo ancora più ottimale (ammesso che tu non abbia qualche informazione sul tipo di alberi che bisogna gestire), potresti considerare questa costante: in un albero binario la quantità di nodi massimi sul livello h è uguale a 2^h (chiaramente).
    Quindi se per trovare il tuo massimo parti dal fondo del vettore (ovviamente la probabilità di trovare la larghezza massima è sui livelli più in fondo), se il numero di nodi sul livello h rispetta questa proprietà hai già trovato la tua risposta e puoi interrompere la ricerca del massimo ottimizzando ancora di più i costi computazionali: 2^(h-1)<numeroNodi[h]. Cioè:
    
    int h //altezza dell'albero
    int[] nodiPerLivello = new int[h] // Lo considero già popolato
    
    public void getMaxLarghezza (int[] nodiPerLivello){
    	int max;
    	for(int i = nodiPerLivello.length()-1; i>=0; i--){
    		if( (2^(i-1)) < nodiPerLivello[i]){  //Cioè se il nodi al livello 'i' sono più dei nodi che massimo possono esistere al livello i-1 quello è già il tuo massimo
    		return nodiPerLivello[i];
    		}
    		if(max<nodiPerLivello[i]){
    			max = nodiPerLivello[i];
    		}
    	}
    	return max;	
    }
    

    Accidenti volevo scriverti due righi ma alla fine mi sono dilungato, spero almeno di essere stato utile ^^
  • Re: Dato un albero determinarne la larghezza

    Sei un grande...grazie mille
Devi accedere o registrarti per scrivere nel forum
4 risposte