Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli


Alberi Binari: Strutture Dati e Algoritmi in Pascal, Dispense di Informatica

Alberi binari

Tipologia: Dispense

2015/2016

Caricato il 16/10/2016

Ciccio.Graziani95
Ciccio.Graziani95 🇮🇹

5

(2)

15 documenti

1 / 5

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
Alberi binari
Una delle strutture fondamentali di tutta la programmazione è l’albero. Esiste un particolare tipo di
albero, detto binario, che per le sue particolari proprietà si presta molto bene ad alcuni tipi di
operazioni, quali l’analisi di espressioni matematiche o la ricerca dicotomica.
Particolari tipi di alberi binari sono utilizzati come nuovi tipi di strutture dati, particolarmente
ottimizzati per operazioni di ricerca o ordinamento: è il caso degli heap, degli alberi di ricerca e così
via.
In questo fascicolo analizzeremo tutti gli algoritmi basilari per la gestione di un albero binario,
partendo dalle definizioni e ragionando su ogni algoritmo.
Il linguaggio scelto per la stesura dei programmi è il Pascal.
Naturalmente questo fascicolo è dedicato esclusivamente alla parte relativa all’albero binario come
struttura dati, quindi tutti i discorsi relativi alla sintassi del linguaggio adottato sono dati per
scontati. In particolare, è bene avere buona padronanza delle strutture, dei puntatori e delle funzioni
ricorsive, anche se quest’ultimo punto è presente una piccola digressione.
Teoria degli alberi binari
Definizioni
Si definisce albero binario un insieme, eventualmente vuoto, di nodi connessi da archi detti rami.
Un particolare nodo è detto radice e ogni nodo è tale da essere collegato a due sottoinsiemi distinti
e disgiunti, anch’essi alberi binari (sottoalbero sinistro e destro).
Fig 1 Esempio di albero binario
Nell’albero mostrato in Figura 1, la radice è il nodo A, da cui si diramano altri due sottoalberi
binari.
A
BC
D
F
E
G
I
H
L
N
M
pf3
pf4
pf5

Anteprima parziale del testo

Scarica Alberi Binari: Strutture Dati e Algoritmi in Pascal e più Dispense in PDF di Informatica solo su Docsity!

Alberi binari

Una delle strutture fondamentali di tutta la programmazione è l’albero. Esiste un particolare tipo di albero, detto binario, che per le sue particolari proprietà si presta molto bene ad alcuni tipi di operazioni, quali l’analisi di espressioni matematiche o la ricerca dicotomica. Particolari tipi di alberi binari sono utilizzati come nuovi tipi di strutture dati, particolarmente ottimizzati per operazioni di ricerca o ordinamento: è il caso degli heap, degli alberi di ricerca e così via. In questo fascicolo analizzeremo tutti gli algoritmi basilari per la gestione di un albero binario, partendo dalle definizioni e ragionando su ogni algoritmo. Il linguaggio scelto per la stesura dei programmi è il Pascal. Naturalmente questo fascicolo è dedicato esclusivamente alla parte relativa all’albero binario come struttura dati, quindi tutti i discorsi relativi alla sintassi del linguaggio adottato sono dati per scontati. In particolare, è bene avere buona padronanza delle strutture, dei puntatori e delle funzioni ricorsive, anche se quest’ultimo punto è presente una piccola digressione.

Teoria degli alberi binari

Definizioni

Si definisce albero binario un insieme, eventualmente vuoto, di nodi connessi da archi detti rami. Un particolare nodo è detto radice e ogni nodo è tale da essere collegato a due sottoinsiemi distinti e disgiunti, anch’essi alberi binari ( sottoalbero sinistro e destro). Fig 1 Esempio di albero binario Nell’albero mostrato in Figura 1, la radice è il nodo A, da cui si diramano altri due sottoalberi binari. A B (^) C D F E G I H L M N

Terminologia

Un nodo si dice foglia se non ha figli. I nodi che non sono foglie sono detti nodi interni. Nell’esempio precedente, sono foglie i nodi F, I, M e N. Dati due nodi i e j, si definisce cammino o percorso da i a j la sequenza di rami da percorrere per passare da i a j.

Proprietà

In un albero, esiste sempre un cammino che collega una arbitraria coppia di nodi. Si definisce profondità o livello di un nodo i , la sua distanza dalla radice, ossia il numero di archi da percorrere (ovviamente, nel caso migliore) per raggiungere i partendo dalla radice. Per convenzione la radice ha profondità 0. Si definisce altezza o profondità di un albero binario l’altezza massima delle sue foglie. Nell’esempio precedente, l’albero ha altezza 5. E’ possibile stabilire dei legami di parentela tra i nodi, del tutto simili a quelli della vita reale: la radice è il padre o genitore dei due nodi a lui connessi, che quindi saranno suoi figli. I figli di uno stesso genitore sono fratelli. Allo stesso modo si possono stabilire i legami di parentela nonno, zio ecc… Ogni nodo di un albero ha un solo genitore e, nel caso degli alberi binari, al massimo due figli. Un albero binario si dice pieno se sono soddisfatte contemporaneamente queste condizioni:

  1. tutte le foglie hanno lo stesso livello
  2. tutti i nodi interni hanno esattamente 2 figli Un albero binario pieno, formato da n nodi, ha profondità uguale a: L = ⌊log^2 ( n )⌋ Notare che con le parentesi quadrate inferiormente si intende l’approssimazione per difetto (le parentesi quadrate superiormente intendono invece l’approssimazione per eccesso). Un albero binario pieno, di altezza h, ha un numero di nodi pari esattamente a: n = 2 h + 1 − 1 Un albero binario è bilanciato quando tutte le foglie hanno lo stesso livello, con un margine di errore di 1. Quindi, se l’altezza dell’albero è h, tutte le foglie dovranno avere livello h o al più h-1. Un albero binario bilanciato in cui tutte le foglie hanno livello h si dice perfettamente bilanciato. L’ attraversamento (o visita) di un albero consiste nell’elencarne tutti i nodi una e una sola volta.

Alberi binari di ricerca

Un albero binario di ricerca (ABR, oppure BST dall’inglese Binary Search Tree ) è un albero binario in cui tutti gli elementi del sottoalbero sinistro sono minori della radice, tutti gli elementi del sottoalbero destro sono maggiori della radice e con l’ulteriore vincolo per cui anche i due sottoalberi sono alberi binari di ricerca a loro volta. Non sono ammessi elementi duplicati. Fig. 2 Esempio di albero binario di ricerca In modo intuitivo si può capire come una struttura dati del genere sia particolarmente indicata per inserimenti ordinati e per la ricerca di tipo dicotomico (che viene anche detta binaria). Una particolare proprietà dei BST è che la visita simmetrica fornisce gli elementi esattamente in ordine crescente. Infatti, visitanfo l'albero di figura 2 in modo simmetrico si ottiene la sequenza: 12 15 20 25 60 66 78 84 93

Implementazione di un albero binario

Struttura di un albero binario

La prima cosa che dobbiamo affrontare è la scrittura del codice che ci permetterà di definire ogni nodo di un albero binario. E’ chiaro che ogni struttura avrà almeno un campo di tipo informativo, più due puntatori ad altri nodi, che sono il figlio sinistro ed il figlio destro. Come convenzione stabiliamo che, se un nodo non ha uno o alcuno dei figli, i puntatori avranno come valore NIL. Inoltre l'inserimento dell'albero viene fatto utilizzando la sua rappresentazione lineare, che nel caso degli alberi binari è del tipo: Radice Figlio_sx Figio_dx e laddove ci dovesse essere una foglia questa va rappresentata con il simbolo"punto". Per l'albero di figura 1 la rappresentazione lineare è: A B D. F.. C. E G I... H L M.. N... 25 60 12 15 84 78 66 93 20

Per quanto riguarda la codifica, l'algoritmo che segue illustra l'allocazione dell'albero binario: program crea_albero_binario; uses crt; type binario=^nodo; nodo=record inf:char; sx, dx :binario; end; var albero : binario; esse : string; procedure alloca(var t:binario;var s:string); var c : char; begin c:=s[1]; delete(s,1,1); if c<>'.' then begin new(t); t^.inf:=c; alloca(t^.sx,s); alloca(t^.dx,s); end else t:=nil; end; procedure visita(t:binario); begin if t<>nil then begin write(t^.inf); visita(t^.sx); visita(t^.dx) end else write('-') end; { MAIN Program} begin clrscr; readln(esse); alloca(albero,esse); visita(albero) end. La procedura di visita serve solo per verificare il corretto funzionamento dell’algortimo di allocazione.