Più breve ramo di un albero binario?

voti
1

Un albero binario può essere codificato utilizzando due funzioni le r in modo tale che per una node n, l(n)dare al bambino sinistra n, r(n) dà il diritto del bambino di n.

Un ramo di un albero è un percorso dalla radice ad una foglia, la lunghezza di un ramo di un particolare foglia è il numero di archi sul percorso dalla radice a quella foglia.

Lasciare MinBranch(l,r,x)essere un semplice algoritmo ricorsivo per prendere un albero binario codificato da L e R funzioni insieme con il nodo radice x per l'albero binario e restituisce la lunghezza del ramo più corto albero binario.

Dare il pseudocodice per questo algoritmo.

OK, in modo sostanzialmente questo è quello che mi è venuta in mente finora:

MinBranch(l, r, x)
{
    if x is None return 0

    left_one = MinBranch(l, r, l(x))

    right_one = MinBranch(l, r, r(x))

    return {min (left_one),(right_one)}
}

Ovviamente questo non è grande o perfetto. Sarei grato se la gente può aiutarlo ad ottenere questo perfetto e di lavoro - qualsiasi aiuto sarà apprezzato.

È pubblicato 28/08/2009 alle 05:07
fonte dall'utente
In altre lingue...                            


5 risposte

voti
3

Dubito che qualcuno possa risolvere i compiti a casa per voi straight-up. Un indizio: il valore di ritorno deve sicuramente crescere più alto come l'albero diventa più grande, giusto? Tuttavia non vedo alcun costanti numeriche nella vostra funzione, a meno 0, e non operatori di addizione entrambi. Come sarà mai tornare i numeri più grandi?

Un altro angolo sulla stessa questione: ogni volta che si scrive una funzione ricorsiva, aiuta a elencare "cosa sono tutte le condizioni in cui dovrei smettere di chiamare me ciò che io ritorno in ogni circostanza?"

Risposto il 28/08/2009 a 05:15
fonte dall'utente

voti
2

Sei sulla giusto approccio, ma non siete abbastanza lì; il vostro algoritmo ricorsivo restituisce sempre 0. (la logica è quasi giusto, però ...)

notare che la lunghezza dei rami secondari è uno inferiore alla lunghezza del ramo; così left_onee right_onedovrebbe essere 1 + MinBranch....

Steping attraverso l'algoritmo con alcuni alberi campione vi aiuterà a scoprire gli errori di off-by-one come questo ...

Risposto il 28/08/2009 a 05:16
fonte dall'utente

voti
0

Quello che hai creato può essere pensato come una ricerca in profondità. Tuttavia, dato quello che stai dopo (più breve ramo), questo non può essere l'approccio più efficiente. Pensate a come il vostro algoritmo si comporta su un albero che era molto pesante sul lato sinistro (del nodo principale), ma aveva un solo nodo sul lato destro.

Suggerimento: prendere in considerazione un approccio di ricerca breadth-first.

Risposto il 28/08/2009 a 05:19
fonte dall'utente

voti
0

Quello che hai lì appare come un primo algoritmo di ricerca approfondita che dovrà cercare l'intero albero prima si arriva con una soluzione. quello che vi serve è la prima ricerca ampiezza algoritmo che può tornare non appena trova la soluzione senza fare una ricerca completa

Risposto il 28/08/2009 a 05:19
fonte dall'utente

voti
1

Sembra quasi avete, ma considera questo esempio:

      4

   3     5

Quando si traccia attraverso MinBranch, vedrai che nella tua MinBranch(l,r,4)chiamata:

left_one = MinBranch(l, r, l(x))
         = MinBranch(l, r, l(4))
         = MinBranch(l, r, 3)
         = 0

Questo ha senso, dopo tutto, 3 è un nodo foglia, così naturalmente la distanza dal nodo foglia più vicino è 0. Lo stesso accade per right_one.

Ma poi finisce qui:

return {min (left_one),(right_one)}
     = {min (0), (0) }
     = 0

ma questo è chiaramente sbagliato, perché questo nodo (4) non è un nodo foglia. Il tuo codice dimenticato di contare il nodo corrente (oops!). Sono sicuro che si riesce a sistemare le cose.


Ora, in realtà, il loro modo si sta facendo questo non è il più veloce, ma non sono sicuro se questo è rilevante per questo esercizio. Considerate questo albero:

         4
       3   5
     2
   1

Il vostro algoritmo conterà il ramo di sinistra in modo ricorsivo, anche se potrebbe, ipoteticamente, bail out se prima contato il ramo di destra e ha osservato che 3 ha un sinistro, quindi il suo nettamente più lunghi di 5 (che è una foglia). Ma, naturalmente, contando il ramo di destra prima non funziona sempre!

Invece, con il codice più complicato, e probabilmente un compromesso di maggior utilizzo della memoria, è possibile controllare i nodi da sinistra a destra, dall'alto verso il basso (come ordine di lettura inglese) e fermarsi alla prima foglia si trova.

Risposto il 28/08/2009 a 05:20
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more