La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Mergesort1 if (n>1) /* la collezione contiene almeno due elementi. */ {1. Dividi la collezione in due di circa la metà degli elementi. 2. chiamata ricorsiva.

Presentazioni simili


Presentazione sul tema: "Mergesort1 if (n>1) /* la collezione contiene almeno due elementi. */ {1. Dividi la collezione in due di circa la metà degli elementi. 2. chiamata ricorsiva."— Transcript della presentazione:

1 mergesort1 if (n>1) /* la collezione contiene almeno due elementi. */ {1. Dividi la collezione in due di circa la metà degli elementi. 2. chiamata ricorsiva di mergesort sulla prima metà. 3. chiamata ricorsiva di mergesort sulla seconda metà. 4. fusione (merging) delle due metà ordinate. } Pseudocodice per il mergesort

2 mergesort2 Implementazione su liste concatenate if (n>1) /* la lista concatenata contiene almeno due elementi. */ {1. Dividi la lista in due metà. /* passo 1 ha un costo lineare, opera localmente */ 2. chiamata ricorsiva di mergesort sulla prima metà. 3. chiamata ricorsiva di mergesort sulla seconda metà. 4. fusione (merging) delle due metà ordinate. /*passo 4 ha un costo lineare, opera localmente */ }

3 mergesort3 Due modi di dividere una lista in due sottoliste di circa uguale lunghezza: Idea 1: Si creano una lista contenente gli elementi di posto pari, e una con quelli di posto dispari ( solo spostando puntatori) Idea 2: Si usa usano due puntatori per scorrere la lista, uno avanza di un record alla volta e laltro di due, quando il secondo ha raggiunto la fine della lista, si usa il primo puntatore come puntatore iniziale della seconda lista. Implementazione su liste concatenate

4 mergesort4 Implementazione su vettori if (n>1) /* il vettore contiene almeno due elementi. */ {1. Dividi il vettore in due metà. /*Passo 1 facile: costo costante */ 2. chiamata ricorsiva di mergesort sulla prima metà. 3. chiamata ricorsiva di mergesort sulla seconda metà. 4. fusione (merging) delle due metà ordinate /* Passo 4 ha costo lineare nella somma delle dimensioni dei due vettori da fondere e necessita di un vettore di appoggio */ }

5 mergesort5 void merge_sort (ELEMENT v[], int start, int end) { int middle; if (start < end) /* ci sono almeno 2 elementi */ { middle = (start + end) / 2; /* calcola il punto mediano */ merge_sort (v, start, middle); merge_sort (v, middle+1, end); merge (v, start, middle, end); /* fonde le due metà ordinate */ } Implementazione su vettori:

6 mergesort6 void merge(ELEMENT v[], int start, int middle, int end) { /* fonde i sottovettori v[start..middle] e v[middle+1..end], restituendo il risultato in v. *prec: v[start]<=…<=v[middle] && v[middle+1]<=…<=v[end] Postc: v[start]<=…<=v[end] */ ELEMENT a[]; int m = start, p = middle +1,q = start; /* m è l'indice di scorrimento della prima metà, p della seconda, q del nuovo vettore nel quale viene temporaneamente memorizzato il vettore ordinato risultante */ while ((m <= middle) && (p <= end)) /*invariante: a[start]<=…<=a[q] */ if (v[m] <= v[p]) {a[q] = v[m]; m = m+1;} else {a[q] = v[p]; p = p+1;} q = q+1;} if (m end) ha provocato l'uscita dal while */ do a[q] = v[m]; m = m+1; q = q+1 while (q > end); /* l'uscita si è avuta per (m > middle), non c'è bisogno di fare niente: gli elementi v[p],...,v[end] sono già al posto giusto */ for (m = start; m < q; m++) v[m] = a[m]; }

7 mergesort m p q m p Chiamata merge(v,0,3, 7); uscita (p > end) while ((m <= middle) && (p <= end)) { if (v[m] <= v[p]) {a[q] = v[m]; m = m+1;} else {a[q] = v[p]; p = p+1;} q = q+1;} if (m end) ha provocato l'uscita dal while */ do a[q] = v[m]; m = m+1; q = q+1 while (q > end); v= a= v=

8 mergesort m p q q Chiamata merge(V,0,3, 7); uscita (p > end) while ((m <= middle) && (p <= end)) { if (v[m] <= v[p]) {a[q] = v[m]; m = m+1;} else {a[q] = v[p]; p = p+1;} q = q+1;} if (m end) ha provocato l'uscita dal while */ do a[q] = v[m]; m = m+1; q = q+1 while (q > end); v= a=

9 mergesort m p q m p Chiamata merge(v,0,3, 7);uscita (m > middle) while ((m <= middle) && (p <= end)) { if (v[m] <= v[p]) {a[q] = v[m]; m = m+1;} else {a[q] = v[p]; p = p+1;} q = q+1;} if (m end) ha provocato l'uscita dal while */ do a[q] = v[m]; m = m+1; q = q+1 while (q > end); /* l'uscita si è avuta per (m > middle) : gli elementi v[p],...,v[end] sono già al posto giusto */ for (m = start; m < q; m++) v[m] = a[m]; v= a= v=

10 mergesort10 while ((m <= middle) && (p <= end)) /*invariante: a[start]<=…<=a[q] */ if (v[m] <= v[p]) {a[q] = v[m]; m = m+1;} else {a[q] = v[p]; p = p+1;} q = q+1;} Invariante vero allinizio, perchè q=start. Supponendo vero linvariante all(i-1)-sima esecuzione, con m < middle e p < end, facciamo vedere che è vero per li-sima, formalmente: Dimostriamo che a[start] a[start]<=…<=a[i] dopo li-sima esecuzione. Caso 1: i=q e ((m=m e p = p+1) Caso 2 : i=q e (m = m+1 e p = p) Caso 1 v[m] <= v[p] ? Se sì caso 1.1 se no caso 1.2. Caso 1.1 a[q] = v[m], è a[q-1] <=a[q] ? Sì perché a[q-1] = v[p] e v[p] <= v[m] Caso 1.2 a[q] = v[p], è a[q-1] <=a[q] ? Sì perché a[q-1] = v[p] e v[p] <= v[p] Caso 2 v[m] <= v[p] ? Se sì caso 2.1 se no caso 2.2. Caso 2.1 a[q] = v[m], è a[q-1] <=a[q] ? Sì perché a[q-1] = v[m] e v[m] <= v[m] Caso 2.2 a[q] = v[p], è a[q-1] <=a[q] ? Sì perché a[q-1] = v[m] e v[m] <= v[p]

11 mergesort11 mergeSort(a,0, 3); mergeSort(a,2,3); mergeSort(a,0,1); merge(a,0,1,1); mergeS(a,0,0); mergeS(a,1,1); merge(a,0,1,3); merge(a,2,2,3); mergeSort(a,2,2);mergeS(a,3,3);

12 mergesort12 Supponiamo il numero degli elementi n sia pari a 2 h e valutiamo l albero delle chiamate della merge: al livello 0 num. chiamate = 1, ciascuna di costo <= 2 h, tot. <= 2 h al livello 1 num. chiamate = 2, ciascuna di costo <= 2 h-1,tot. <= 2 h al livello 2 num. chiamate = 4, ciascuna di costo <= 2 h-2,tot. <= 2 h... al livello h num. chiamate <=2 h, ciascuna di costo =1, tot. <= 2 h In totale costo <= h *2 h, cioè costo <= n*log 2 (n)


Scaricare ppt "Mergesort1 if (n>1) /* la collezione contiene almeno due elementi. */ {1. Dividi la collezione in due di circa la metà degli elementi. 2. chiamata ricorsiva."

Presentazioni simili


Annunci Google