Heap binomiale: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
+ immagine |
m →Altri progetti: Aggiunto il parametro "Preposizione" nel template "Interprogetto" |
||
(27 versioni intermedie di 16 utenti non mostrate) | |||
Riga 1:
{{F|programmazione|febbraio 2013}}
{{S|informatica}}▼
{{S|programmazione}}
[[File:Binomial-heap-13.svg|thumb|
Un '''heap binomiale''' è un insieme di [[Albero binomiale|alberi binomiali]] che soddisfa le seguenti proprietà:
# per qualsiasi intero <math>k</matH> non negativo esiste al più un albero binomiale la cui radice ha grado <math>k</math>
# ogni albero binomiale gode della proprietà di ordinamento parziale degli [[Heap (struttura dati)|heap]], ossia ogni nodo di ciascun albero è tale che la propria chiave sia sempre maggiore o uguale della chiave del nodo padre.
▲[[File:Binomial-heap-13.svg|thumb|right|300px|Esempio di heap binomiale costituito da 13 nodi con chiavi distinte. Lo heap è costituito da 3 [[albero binomiale|alberi binomiali di grado rispettivamente 0, 2 e 3]]
Gli heap binomiali appartengono alla classe di strutture dati definite come ''heap aggregabili'' ossia strutture dati di tipo heap che oltre alle consuete procedure di ricerca della chiave minima, inserimento di un nodo, estrazione del nodo con chiave minima ed eliminazione di una chiave (operazioni implementate ad esempio negli [[Heap binario|heap binari]]), consentono anche l'implementazione dell'operazione di ''unione'' fra due heap che, a partire da due heap iniziali, restituisce un unico heap il cui insieme delle chiavi è pari all'unione degli insiemi delle chiavi dei due heap di partenza.
== Creazione di uno heap binomiale ==
La procedura di creazione restituisce uno heap binomiale vuoto e richiede tempo di esecuzione <math>\Theta(1)</math>. Il puntatore ''head[H]'' punterà alla testa della lista delle radici dello heap.
Make-Heap()
==Ricerca della chiave minima==▼
crea H ed assegna ad esso spazio di memoria
Ogni albero binomiale che costituisce uno heap binomiale gode della proprietà di ordinamento parziale degli heap, pertanto ognuno di essi avrà la chiave minima in corrispondenza della radice. La chiave minima dello heap binomiale sarà, quindi, contenuta, in uno dei nodi radice dei vari alberi binomiali che lo costituiscono, di conseguenza la ricerca della chiave minima si riduce ad una ricerca del minimo nella lista delle radici degli alberi binomiali. Il numero massimo di radici di alberi binomiali di uno heap binomiale è al più <math>\lfloor lgn \rfloor +1</math> dunque il tempo per l'esecuzione della ricerca è <math>O(lgn)</math>.▼
head[H] ← NIL
return H
▲== Ricerca della chiave minima ==
▲Ogni albero binomiale che costituisce uno heap binomiale gode della proprietà di ordinamento parziale degli heap, pertanto ognuno di essi avrà la chiave minima in corrispondenza della radice. La chiave minima dello heap binomiale sarà, quindi, contenuta, in uno dei nodi radice dei vari alberi binomiali che lo costituiscono, di conseguenza la ricerca della chiave minima si riduce ad una ricerca del minimo nella lista delle radici degli alberi binomiali. Il numero massimo di radici di alberi binomiali di uno heap binomiale è al più <math>\lfloor
==
Dato che un albero binomiale, per sua definizione, contiene esattamente <math>2^k</math> nodi al suo interno, con <math>k</math> grado dell'albero, deduciamo che uno heap binomiale possa contenere un qualsiasi numero di nodi al suo interno, componendo alberi binomiali di gradi diversi, esattamente come una cifra binaria è espressa in funzione delle diverse potenze di 2.
L'operazione di inserimento di un nodo in uno heap binomiale consiste nella creazione di un nuovo heap binomiale costituito solo dal nodo da inserire (con tempo di esecuzione <math>O(1)</math>) e in una successiva operazione di unione dello heap binomiale originale con lo heap binomiale appena creato (operazione che richiede tempo di esecuzione <math>O(lgn)</math>). Il tempo complessivo di esecuzione è pertanto <math>O(lgn)</math>.▼
La somma di due heap binomiali avviene esattamente come la somma tra due numeri binari, dove un <math>1</math> in posizione <math>k</math> indica la presenza di un albero di grado <math>k</math> all'interno della struttura. Lo heap binomiale risultante avrà di conseguenza la stessa struttura del numero decimale risultato della somma.
Union(H1, H2)
==Estrazione del nodo con chiave minima==▼
Creo una nuova lista contenente tutti gli alberi binomiali di H1 e H2 ordinati per grado
Per ogni albero x della lista:
next <- next[x];
sibling <- next[next];
if(rank[x] == rank[next])
if(rank[next] == rank[sibling])
merge(next, sibling);
else
merge(x, next);
x <- next;
Merge(H1, H2)
Pongo H2 come figlio della radice di H1
L'algoritmo di unione crea un'unica lista dinamica contenente tutti gli alberi binomiali ordinati per grado crescente.
Dopodiché scorre ogni elemento (che sarà la radice di un albero binomiale) osservando i suoi due elementi successivi.
== Inserimento di un nodo ==
▲L'operazione di inserimento di un nodo in uno heap binomiale consiste nella creazione di un nuovo heap binomiale costituito solo dal nodo da inserire (con tempo di esecuzione <math>O(1)</math>) e in una successiva operazione di unione dello heap binomiale originale con lo heap binomiale appena creato (operazione che richiede tempo di esecuzione <math>O(
▲== Estrazione del nodo con chiave minima ==
L'operazione di estrazione del nodo con chiave minima prevede l'eliminazione dallo heap binomiale del nodo con chiave minima restituendone il puntatore. Tale procedura consta di tre fasi e si supponga di indicare con <math>H</math> lo heap binomiale di partenza:
# si cerca la radice con la chiave minima e la si elimina dalla lista delle radici degli alberi binomiali,
Line 26 ⟶ 51:
# si inverte la lista dei figli della radice precedentemente eliminata e si considera come testa della nuova lista delle radici il puntatore al primo nodo ottenuto,
# si effettua, infine, l'operazione di unione tra gli heap <math>H</math> e <math>H'</math>.
La procedura impiega tempo di esecuzione <math>O(
== Decremento di una chiave ==
L'operazione di decremento di una chiave consiste nel sovrascrivere il valore del nodo con un nuovo valore strettamente minore. Quindi, dato un heap binomiale <math>H</math>, il puntatore <math>x</math> al nodo da modificare e la nuova chiave <math>k</math> da inserire in <math>x</math>, la procedura consta di 3 fasi:
# si verifica che il valore <math>k</math> sia strettamente minore del valore della chiave attualmente presente nel nodo <math>x</math>,
# si sovrascrive il valore della chiave del nodo <math>x</math> con il valore <math>k</math>,
# utilizzando due puntatori <math>y</math> e <math>z</math> che inizialmente puntano al nodo <math>x</math> e al nodo padre di <math>x</math>, si verifica se la chiave del nodo <math>x</math> è minore della chiave del nodo <math>z</math> e in tal caso si scambiano le chiavi dei due nodi. Dopo lo scambio i puntatori <math>y</math> e <math>z</math> vengono aggiornati e punteranno rispettivamente al vecchio nodo puntato da <math>z</math> e al nodo padre di <math>z</math>. Questa fase viene ripetuta fino a quando la condizione di disuguaglianza delle chiavi non viene più soddisfatta o fino a quando <math>z</math> punta ad una locazione di memoria nulla.
La procedura impiega tempo di esecuzione <math>O(\log n)</math>.
== Eliminazione di una chiave ==
L'operazione di
# si decrementa al minimo valore
# si
Le due operazioni richiedono rispettivamente tempo di esecuzione <math>O(
== Bibliografia ==
* Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, ''Introduzione agli algoritmi''. Jackson Libri, 2003, ISBN 88-256-1421-7.
== Altri progetti ==
[[Categoria:Strutture dati]]▼
{{interprogetto|preposizione=sull'}}
{{strutture dati}}
|