Sei sulla pagina 1di 1

MergeSort( a, sinistra, destra ):

if (sinistra < destra) {


centro = (sinistra+destra)/2;
MergeSort( a, sinistra, centro );
MergeSort( a, centro+1, destra );
Fusione( a, sinistra, centro, destra );}
Fusion: 1 Confr i 2 elem + piccoli delle
2 seq. 2 L'elem + picc viene rimosso
dalla seq e inserito alla fine della seq out
3 Eseguiamo i 2 passi prec finche una seq
sar vuota e cos aggiugniamo direttamente
I passi 1 e 2 possono esse esuguiti al max
m-1 volte poich una rimane vuota.
k=passi1e2 k<m, qnd una seq sar vuota
l' altra avr m-k elem da spostare
Fusione( a, sx, cx, dx ):
i = sx; j = cx+1; k = 0;
while ((i <= cx) && (j <= dx))
{if (a[i] <= a[j]) {
b[k] = a[i]; i = i+1;
} else {
b[k] = a[j]; j = j+1;}
k = k+1;}
for ( ; i <= cx; i = i+1, k = k+1)
b[k] = a[i];
for ( ; j <= dx; j = j+1, k = k+1)
b[k] = a[j];
for (i = sx; i <= dx; i = i+1)
a[i] = b[i-sx];
tempo per decom il prob in due sottopro O(1),
tempo per eseg le 2 chiam ricorsive: T(n/2) +
T(n/2),
tempo per fondere le due seq cn = O(n).
il tempo totale O(nlogn)
T(n) c0 se n 1
2T(n/2) + cn altrimenti

QuickSelect( a, sinistra, r, destra ):


if (sinistra == destra) {
return a[sinistra];
} else {
scegli pivot nellintervallo
[sinistra...destra];
indiceFinalePivot = Distribuzione(a,
sinistra, pivot, destra);
if (r-1 == indiceFinalePivot) {
return a[indiceFinalePivot];
} else if (r-1 < indiceFinalePivot) {
return QuickSelect( a, sinistra, r,
indiceFinalePivot-1 );
} else {
return QuickSelect( a,
indiceFinalePivot+1, r, destra );}}
Serve a trovare l' elemento di rango r in
un array non ordinato.
Caso base: Se il segmento contiene un
solo elem allora l' algo esegue un numero
cost di operazioni. Se l' indice restituito
da distr = r-1 l' algo termin e il suo
costo dipende da Distr che eseg c1n
oper.
Pass Rico: il numero di operazioni
eseguite al pi pari a cn (c
costante) piu il numero di operazioni
richieste per effettuare la selezione
nel segmento degli elementi minori o
uguali del pivot oppure in quello
degli elementi maggiori o uguali del
pivot.
T(n) { c1n se n1 o rp=r-1
max{T(rp-1),T(n-rp)}+cn altrim
CasPes O(n2) CasOtt O(n) CasMedO(n)

RicercaBinariaRicorsiva( a,k,sinistra,destra )
:
if (sinistra > destra) {
return -1;}
c = (sinistra+destra)/2;
if (k == a[c]) {
return c;}
if (sinistra==destra) {
return -1;}
if (k <a[c]) {
return RicercaBinRico( a,k,sinistra,c-1 );
} else {
return RicercaBinRico( a,k,c+1,destra );}
Caso base: Il segmento in cui stiamo
effettuando la ricerca contiene al piu
un elemento oppure abbiamo trovato
lelemento al centro del segmento
Per decomporre occorre vedere se k `e
minore o maggiore di a[c], non serve lavoro
di ricombinazione.

Distribuzione/ Quicksort
Decom: se la sequenza ha almeno due
elementi, scegli un elemento pivot e dividi
la seq in due sotto-seq: la prima contenga
elementi minori o uguali al pivot e la
seconda gli elementi maggiori o uguali del
pivot.
Si ordinano ricorsivamente le due
sottosequenze.

T(n) c0 se n 1 o k==a[c]
T(n/2) + c altrimenti
Tempo O(logn)

Data la posizione px del pivot in un


segmento a[sx, dx]:
scambia gli elementi a[px] e a[dx],
se px dx
usa due indici i e j per scandire il segmento:
i parte da sx e va verso destra e j parte da
dx 1 e va verso sinistra fino a quando i
j, ogni volta che si ha a[i] > pivot e a[j] <
pivot, scambia a[i] con a[j] e poi riprende la
scansione
alla fine della scansione posiziona il pivot
nella sua posizione corretta.

Sia A un algoritmo di ricerca che usa


confronti tra coppie di elementi: A deve
discernere tra n + 1 situazioni (lelemento
cercato appare in una delle n posizioni
dellinsieme oppure non appare
nellinsieme)
A esegue dei confronti, ognuno dei quali da
luogo a tre possibili risposte in [<, >, =]
Se A effettua t confronti ci sono 3t possibili
sequenze di risposte.
Dopo t confronti di elementi, lalgoritmo A
puo discernere al piu 2^t situazioni.
Poiche le situazioni da discernere sono n +
1, deve valere 3^t n + 1.
Ne deriva che occorrono t log3(n + 1) =
(log n) confronti: ci rappresenta un limite
inferiore per il problema della ricerca per

Il prob si pu ris confronta tutte le coppi in


O(n^2). Col DivetImp si pu ris in O(nlogn)
Con 1 linea vert dividiamo in S e D.
Troviamo ricors le sol per S e D cio ds e dD
La sol o una copp gia trovat, oppure un
punto in S e uno in D. dSD= min dist tra
estremin in S e D.
La sol finale min{d SD, ds, dD}
DivetImp: Decom: partizionare l' insieme di
punti in S e D. Soluzione sottoproblemi:
cerca la coppia minima dS in S e dD in D.
d=min{dS,dD} Ricomb: cerca tra le coppie
(p,q), p in S e q in D, la coppia dSD e
restituisce min{d, dSD}
S'= punti in S con ascissa [x-d,x]
D'= punti in D con ascissa[x,x+d]
Cerchiamo (p,q), p in S' e q in D'. Dividiamo
S' e D' in quadrati di d/2. Ogni quadrato
contiene un solo punto.
Se un punto p di S' si trova nella colonna dei
quadrati di Sx allora il punto q che si trova
in D' si trova nei quadrati pi a sinistra di D.
Se q pi in alto rispetto a p allora q si trova
in 1,2,3 altrimenti in 4,5.
Se un punto p di S' si trova in uno dei
quadrati confinanti con L allora un punto q
di D' a dist min di d da q pu trovarsi solo in
uno dei quadrati di D' numerati.
Px = array dei punti ordinato in modo non
decrescente rispetto alle
ascisse; Py = array dei punti ordinato in
modo non decrescente rispetto
alle ordinate, n dimensione degli array Px
e Py
1) Se n <= 3, calcola le distanze tra le tre
coppie di punti per trovare la
coppia a distanza minima.
2) Se n > 3, esegue i seguenti passi:
3) Inserisce nellarray Sx i primi n/2 punti di
Px e nellarray Dx gli ultimi
n/2 punti di Px
4) Inserisce nellarray Sy i primi n/2 punti di
Px nellordine in cui appaiono
in Py e nellarray Dy gli ultimi n/2 punti di
Px nellordine in cui
appaiono in Py
5) Effettua una chiamata ricorsiva con
input Sx , Sy e n/2 e una chiamata
ricorsiva con input Dx , Dy e n/2. Siano dS e
dD i valori delle distanze
delle coppie di punti restituite dalla prima e
dalla seconda chiamata
rispettivamente. Pone d = min{dS , dD} e
(p, q) uguale alla coppia a
distanza d.
6) Copia in Pd i punti a distanza minore di
d dalla retta verticale passante
per lelemento centrale di Px nello stesso
ordine in cui appaiono in Py
7) Per ciascun punto p' in Pd esamina i 10
punti che seguono p' in Pd; per
ciascun punto q' (tra questi 10) computa la
sua distanza da p' e se questa
risulta minore di d, aggiorna il valore di d e
pone (p, q) = (p',q')
8) Restituisce la coppia (p, q)
T(n) c0 se n 2
2T(n/2)+cn altrimenti
T(n)= O(nlogn)

QuickSort( a, sinistra, destra ):


if (sinistra < destra) {
scegli pivot nellintervallo
[sinistra...destra];
indiceFinalePivot = Distribuzione(a,
sinistra, pivot, destra);
QuickSort( a, sinistra, indiceFinalePivot1 );
QuickSort( a, indiceFinalePivot+1,
destra ); }

Distribuzione( a, sx, px, dx ): T O(n)


if (px != dx) Scambia( px, dx );
i = sx; j = dx-1;
while (i <= j) {
while ((i <= j) && (A[i] <= A[dx]))
i = i+1;
while ((i <= j) && (A[j] => A[dx]))
j = j-1;
if (i < j) Scambia( i, j );
}

T(n){c0 se nc0
T(n/)+cf(n) altrimenti
f(n/)=f(n)
T(n)=O(f(n)) se <1
T(n)= O(f(n)logn) se =1
T(n)= O(nlog) se >1

Dimensione( u ):
if (u == null) {
return 0;
} else {
dimensioneSX = Dimensione( u.sx );
dimensioneDX = Dimensione( u.dx );
return dimensioneSX + dimensioneDX + 1; }
Altezza( u ):
if (u == null) {
return -1;
} else {
altezzaSX = Altezza( u.sx );
altezzaDX = Altezza( u.dx );
return max( altezzaSX, altezzaDX ) + 1; }
simmetrica (inorder):
Simmetrica( u ):
if (u != null) {
Simmetrica( u.sx );
elabora(u);
Simmetrica( u.dx ); }
anticipata (preorder):
Anticipata( u ):
if (u != null) {
elabora(u);
Antiticipata( u.sx );
Antiticipata( u.dx ); }
posticipata (postorder):
Posticipata( u ):
if (u != null) {
Posticipata( u.sx );
Posticipata( u.dx );
elabora(u); }
CompletamenteBilanciato( u ):
if (u == null) {
return <true, -1>;
} else {
<bilSX,altSX> = CompletamenteBilanciato( u.sx );
<bilDX,altDX> = CompletamenteBilanciato( u.dx );
bil = bilSX && bilDX && (altSX == altDX);
altezza = max(altSX, altDX) + 1;
return <bil,altezza>; }
Profondita( u ):
if (u.padre==null) {
return 0; }
return profondita(u.padre)+1;
Cardine( u, p ):
if (u == null) {
return -1;
} else {
altezzaSX = Cardine( u.sx, p+1 );
altezzaDX = Cardine( u.dx, p+1 );
altezza = max( altezzaSX, altezzaDX ) + 1;
if (p == altezza) print u.dato;
return altezza; }
Valuta( u ):
if (u==null) {
return null;}
if (u.sx == null && u.dx==null) {
return u.dato;
} else {
valSinistra=Valuta( u.sx );
valDestra= Valuta( u.dx );
ris= Calcola(u.dato,valSinistra ,valDestra);
return ris; }

Dopo la creazione della foglia f, cerca


il suo nodo critico= minimo antenato u
di f che non pi 1-bilanciato.
Ristruttura l' albero facendo al pi 2
rotazioni: 0 o 1 rot su uni dei figli di u,
1 rotazione su u. Aggiorna anche i
campi antenati di f. Uscendo dalle
chiamate ricorsive sugli antenati di f
percorre tale cammino a ritroso.
La forma dellalbero dipende
dallordine dinserimento delle chiavi
Esempio: chiavi inserite in ordine
crescente o decrescente
Se le chiavi sono inserite in ordine
casuale, lalbero risultante ha altezza
logaritmica in media
Vediamo come garantire altezza
logaritmica al caso pessimo con gli
alberi AVL