2010-10-14 9 views
6

Ho letto alcuni altri articoli qui che sembravano simili, ma non rispondevano del tutto al mio problema. Mi è stata data una domanda per un incarico per assegnare ad ogni nodo di un albero binario la sua rispettiva profondità. Non riesco a capirlo.Assegnazione di una profondità a ciascun nodo

Per riferimento questo è il mio codice:

struct treeNode { 
    int item; 
    int depth; 
    treeNode *left; 
    treeNode *right; 
}; 
typedef treeNode *Tree; 

int assignDepth(Tree &T, int depth) 
{ 
    if(T!=NULL) 
    { 
     depth = assignDepth(T->left, depth++); 
     T->depth = depth; 
     depth = assignDepth(T->right, depth++); 
    } 
    else //leaf 
     return depth--; 
} 

ho provato a fare funzionare attraverso con carta e penna e sembrava OK, ma la mia scrivania controllando le competenze sono chiaramente carente.

Qualcuno può indicarmi la direzione giusta, per favore? Questa è la prima volta che uso gli alberi e la ricorsione non è il mio punto di forza.

Risposta:

void treecoords(Tree &T, int depth) 
{ 
    static int count = -1; //set to -1 so the precrement before assignment doesn't give the wrong values 
    if(T!=NULL) 
    { 
     treecoords(T->left, depth+1); //depth decrements automatically once this function call is removed from the stack 
     count++; 
     T->x = count; 
      T->y = depth; 
     treecoords(T->right, depth+1); 
    } 
} 
+1

Grazie a tutti quelli che hanno risposto al mio post. Capisco che stavo pensando a tutto sbagliato ora. Vado via e cerco di correggere il codice, visto quello che mi hai detto e postare i miei risultati finali. Non voglio semplicemente usare il codice di qualcuno senza comprenderlo appieno (anche se apprezzo che tu l'abbia pubblicato per me, grazie). – xyzjace

+0

Funziona! Ho fatto un algoritmo ricorsivo che ha finito per abbinare il signor Cooper. In realtà fa parte di un algoritmo più grande che assegna le coordinate xey ai nodi dell'albero. L'algoritmo è nella domanda originale ora. – xyzjace

risposta

3

È don' t bisogno

else //leaf 
    return depth--; 

Inoltre non vuole incrementare la variabile di profondità, basta passare la profondità + 1 per la prossima iterazione.

Inoltre, non è necessario restituire un valore.

Prova questa:

void assignDepth(Tree T, int depth) 
{ 
    if(T!=NULL) 
    { 
     assignDepth(T->left, depth+1); 
     T->depth = depth; 
     assignDepth(T->right, depth+1); 
    } 
} 
+0

Non capisco perché no, ma tutti hanno detto di rimuoverlo, così ho fatto. La ricorsione mi rompe la mente. Grazie :) – xyzjace

+0

Aiuta a pensare a quello che sta succedendo. Nella prima call depth = 0 (o qualsiasi altra cosa) e T è la radice dell'albero. Supponendo che T non sia NULL, la funzione si chiama sul sottoalbero sinistro con profondità + 1, assegna la profondità al nodo corrente (radice), quindi chiama sé stesso nel sotto-albero destro, sempre con profondità + 1. È la fase intermedia che assegna il valore del parametro depth al nodo, quindi non è necessario restituire il valore a nessun luogo. –

+0

Questo ha senso. Mi sento un po 'confuso con il ritorno di valore in ricorsione. Ma penso di averlo capito ora. Molto apprezzato :) – xyzjace

2

Beh, per cominciare, si sta utilizzando post-incremento/decremento, probabilmente significava ++depth/--depth per l'assegnazione a destra e l'altro di ritorno;

Inoltre, perché passare un puntatore come variabile di riferimento?

+0

Ho provato il precremento come suggerito e sta arrivando, ma non completamente. Perché dovrei usare il precremento invece del post? Pensavo che dipendesse solo dall'ordine delle operazioni? Sto usando il riferimento a un puntatore perché è così che sembra funzionare.Ci è stata data una breve introduzione ai puntatori, poi sono caduti in un oceano di alberi. È stata un'ipotesi e ho controllato quando il compilatore ha smesso di lanciarmi degli errori. – xyzjace

1
int assignDepth(Tree &T, int depth) 

Hai definito Tree come un puntatore a un treeNode. Non è necessario passarlo per riferimento. È possibile modificare il nodo puntato comunque.

{ 
    if(T!=NULL) 
    { 
     depth = assignDepth(T->left, depth++); 

Il suffisso ++ assicura che si sta passando l'originale depth verso il basso. Non è quello che vuoi. Incrementare depth prima di questo e dimenticarsi di restituirlo come risultato di una funzione.

T->depth = depth; 

Questo è OK.

 depth = assignDepth(T->right, depth++); 

Simile come per il precedente chiamata ricorsiva, solo che qui non si deve modificare depth a tutti perché è già stato incrementato.

} 
    else //leaf 
     return depth--; 

Non è necessario restituire alcuna informazione di profondità (o è un requisito non dichiarato?).

} 

Acclamazioni & hth.,

+0

Ho letto tutti i commenti per assicurarmi di non perdere nulla. Grazie :) – xyzjace

1
  1. Una volta raggiunto un nodo foglia, non si preoccupano di sua profondità più, quindi il valore di ritorno sembra fare nulla.

  2. In due istruzioni:

    depth = assignDepth(T->left, depth++); 
    // and 
    depth = assignDepth(T->right, depth++); 
    

Hai comportamento indefinito di modificare depth due volte senza un punto sequenza intermedio (anche se sembra che ci dovrebbe essere, c'è non un punto sequenza tra i lati destro e sinistro di un incarico).

+0

Ho appena capito perché il valore restituito è ridondante mentre stavo scrivendo questo. L'uomo mi sento stupido. Grazie :)! Non sono sicuro quali siano i punti di sequenza, mi dispiace. – xyzjace

+0

@ user475234: Ho discusso anche solo di menzionarlo, poiché la correzione del codice altrimenti rimuoverà anche questo problema. Con poche eccezioni, C dice fondamentalmente che puoi modificare una particolare variabile solo una volta in una determinata istruzione, e in questo caso lo stai facendo due volte (una volta nell'incremento, una volta nel compito). –

1
  1. Perché si ritorna quando il nodo è NULL. Secondo le vostre specifiche non è necessario restituire alcuna profondità
  2. In altri casi è sufficiente aumentare la profondità e inviare alla chiamata di funzione. Quello che segue è la mia versione del codice

    assignDepth void (Albero & T, int profondità) { se (T == null) ritorno; altro { T-> profondità = profondità; se (T-> left! = NULL) assignDepth (T-> left, depth + 1); se (T-> right! = NULL) assignDepth (T-> right, depth + 1); }}

+0

Sta iniziando a dare un po 'più senso. Ora mi rendo conto che quando la ricorsione è terminata non ha bisogno di restituire la profondità, perché quando estrae la chiamata della funzione dalla pila, la profondità è lo stesso valore che aveva prima di chiamare la funzione. Grazie: D! – xyzjace

1

Ho un design leggermente più complicato con diversi tipi di nodi e fatto questo, così ho pensato quota id.

Se si dispone di un albero che varia nel tipo Nodo su nodo (Binario, Unario ecc.), È opportuno semplificare il metodo tradizionale per evitare che gli IF incorporati scorretti controllino il tipo di nodi.

due funzioni:

  • 1: Dalla radice, attraversano ciascun nodo e controllare la sua distanza dalla radice chiamando recursivly stessa e aggiungendo 1 per ciascun genitore. Dare a ogni nodo una variabile di profondità per archiviarlo.
  • 2: dal set completo di Nodi nella struttura eseguire un controllo MAX in corrispondenza della profondità di ciascun nodo, il numero più alto sarà uguale alla profondità dell'albero .

L'elaborazione in questo modo rimuove il controllo esplicito del tipo e conta semplicemente il nodo, indipendentemente dal fatto che abbia uno, due o cento figli.

Spero che questo aiuti qualcuno!

Problemi correlati