asp - asp.net - aspcode.it

COMMUNITY - Login
 Username:
 
 Password:
 
Voglio registrarmi!
Password dimenticata?
 Utenti on-line: 0
 Ospiti on-line: 12563
ASPCode.it - Store

  > > Articoli

Manipolare strutture ad albero

Data di pubblicazione: 04/04/2003        Voto della community: 1,00 (Votanti: 1)


Spesso abbiamo a che fare con dati strutturati in maniera gerarchica, in cui cioè i dati sono correlati tra loro da relazioni padre-figlio. Supponiamo ad esempio di avere una serie di voci con questo tipo di "parentela" :

Musica Classica
        Bach
                  Fuga N.1
        Chopin
                  Notturno N.1
                  Notturno N.2
Musica Pop
        Francesco De Gregori
                  La donna cannone
                  Generale

Ad esempio la voce "Notturno N.1" è figlia della voce "Chopin" e quest'ultima è figlia della voce "Musica Classica".
Una tipica implementazione di questa struttura è una tabella Voci con

IDvoce
descrizione
IDvocepadre

in cui ogni record corrisponde ad una voce e il rapporto di parentela che lega una voce ad un'altra è descritto dal campo IDvocepadre.
Supponiamo ora di voler visualizzare le varie voci in maniera da chiarire il rapporto di parentela che le lega, ad esempio in maniera simile alla rappresentazione di sopra in cui ogni voce figlia viene visualizzata immediatamente sotto quella padre e con una certa spaziatura rispetto alla posizione di quella padre. Ci serve dunque un sistema capace di trovare tutte le voci figlie di una certa voce e per ciascuna di esse ripetere l'operazione di ricerca in modo da trovare le eventuali voci figlie, fino alla fine della gerarchia.
Questo obiettivo puo' essere raggiunto creando una procedura (Sub) di ricerca delle voci figlie di una certa voce, la quale procedura richiama sé stessa per cercare le voci figlie delle occorrenze trovate (le procedure che richiamano sè stesse sono anche dette 'ricorsive').
Vediamo come implementare questa tecnica.

<%
dim arr (9,2)
arr(0,0)= "100": arr(0,1)="Musica Classica" :    arr(0,2)="0"
arr(1,0)= "101": arr(1,1)="Musica Pop" :          arr(1,2)="0"
arr(2,0)= "102": arr(2,1)="Bach" :                arr(2,2)="100"
arr(3,0)= "103": arr(3,1)="Chopin" :              arr(3,2)="100"
arr(4,0)= "104": arr(4,1)="Notturno N.1" :        arr(4,2)="103"
arr(5,0)= "105": arr(5,1)="Notturno N.2" :        arr(5,2)="103"
arr(6,0)= "106": arr(6,1)="Fuga N.1" :            arr(6,2)="102"
arr(7,0)= "107": arr(7,1)="Francesco De Gregori": arr(7,2)="101"
arr(8,0)= "108": arr(8,1)="La donna cannone" :    arr(8,2)="107"
arr(9,0)= "109": arr(9,1)="Generale" :            arr(9,2)="107"


call Stampafigli ("0",0)


Sub Stampafigli ( idpadre, livello)

dim rip
dim z
dim spazio

for z= 1 to livello
  spazio=spazio&"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
next

for rip = 0 to ubound (arr,1)

  if cint ( arr(rip,2) ) = cint (idpadre) then

      response.write "<br>" & spazio & arr (rip,1)

      call Stampafigli ( cint(arr(rip,0)) ,livello+1)

  end if

next
 
End Sub

%>

Il primo blocco di codice crea le voci sopra indicate con le relative relazioni. Per praticità abbiamo utilizzato come base di dati, anziché una tabella del tipo descritto sopra, un array bidimensionale con struttura del tutto simile a tale tabella. I vari campi (IDvoce, Descrizione, IDvocepadre) di un certo record corrispondono rispettivamente agli elementi arr(x,0) arr(x,1) arr(x,2) dove x corrisponde all'indice dei vari record.
Le voci che non hanno padre (cioé quelle del livello più alto) le abbiamo contrassegnate assegnando "0" al campo idvocepadre, ad es. arr(0,2)="0" e arr(1,2)="0".
Abbiamo quindi chiamato la procedura con

call Stampafigli ("0",0)

dove il primo parametro (cioè "0") sta ad indicare che la procedura deve cercare tutti gli elementi che hanno "0" come IDvocepadre (il significato del secondo parametro lo vedremo tra poco).
Quando la procedura trova nell'array un elemento con IDvocepadre uguale a "0" ne visualizza la descrizione, quindi richiama sé stessa passando come parametro l'ID di tale elemento in modo da trovare eventuali elementi figli di tale elemento e così via.
Per ultimo chiariamo l'utilità del secondo parametro richiesto dalla procedura: questo rappresenta il livello della voce all'interno della gerarchia, necessario per ricavare la spaziatura adeguata per ciascun elemento. Inizialmente alla procedura viene passato 0 come livello (nessuna spaziatura); in seguito, quando la procedura richiama sé stessa per visualizzare eventuali voci figlie, viene passato come valore il livello dell'elemento corrente più uno, in modo che le voci nella chiamata ricorsiva vengano visualizzate con una indentazione maggiore, essendo il numero di spazi lasciati prima di ogni voce dato da:

for z= 1 to livello
  spazio=spazio&"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
next

A voi trovare altre possibili applicazioni di questa tecnica.




Utenti connessi: 12563