Ordinamento di un array (insertion sort) ● Si scandisce l'array dalla seconda posizione e si inserisce ordinatamente l'i-esimo elemento nella porzione di array precedentemente ordinata. insord a porzione di array di i elementi già ordinata nell i-1 iterazioni precedenti i elemento da inserire ordinatamente Insertion sort (sol) void insord(int A[], int k, int x){ k--; while (k >= 0 && A[k]>x){ A[k+1] = A[k]; --k; } A[k+1]=x; } void insertionsort(int A[], int n){ int i; for (i=1; i<n; i++) insord(A,i,A[i]); } Inserisci ordinatamente A[i] in A[0..i-1] Insertion sort: tempo di esecuzione ● ● Il caso peggiore si ha quando gli elementi sono disposti in ordine decrescente. Il numero di operazioni (scambi e confronti) è dato da: iterazione (i) 1 2 3 .. n-1 ● scambi 1 2 3 .. n-1 n−1 2 n⋅n−1 n −n 2 T n=∑ i= = =O n 2 2 1 Se gli elementi sono già ordinati il numero di confronti è pari a n Ordinamento di un array (selection sort) ● Scandisci l'array e all'i-esima iterazione seleziona il più piccolo elemento nella porzione di array dalla i-esima posizione al termine dell'array e scambialo con la posizione i-esima. scambia minore : elemento da scambiare a porzione di array di i elementi già ordinata nell i-1 iterazioni precedenti porzione di array da ordinare Selection sort (sol) int minimo(int A[], int inf, int sup){ int i,m; m=inf; for (i = inf+1; i<=sup; i++) if (A[i]<A[m]) m = i; return m; } void selsort(int A[], int n){ int i; for (i = 0; i < n-1; i++){ int m; m = minimo(A,i,n-1); scambia(&A[i],&A[m]); } } Minimo nella porzione di array: A[inf .. sup] Seleziona il minore nella porzione di array A[i .. n-1] Selection sort (sol alt) int minimo(int A[], int n){ int i,m; m=0; for (i = 1; i < n; i++) if (A[i]<A[m]) m = i; return m; } void selsort(int A[], int n){ int i; for (i = 0; i < n-1; i++){ int m; m = minimo(A+i,n-i)+i; scambia(&A[i],&A[m]); } } Minimo in un array di n elementi Seleziona il minore nella porzione di array A[i .. n-1] Selection sort: tempo di esecuzione ● ● Il caso peggiore si ha quando gli elementi sono disposti in ordine decrescente. Il numero di operazioni è dato da: iterazione (i) 0 1 2 .. n-2 ● confronti n-1 n-2 n-3 .. 1 n−1 2 n⋅n−1 n −n 2 T n=∑ i= = =O n 2 2 1 Se gli elementi sono già ordinati il numero di confronti è ancora O(n2) Ordinamento di un array (bubble sort) ● ● ● Si eseguono scansioni successive dell'array; ad ogni scansione si scambiano elementi successivi fuori ordine. L'algoritmo termina quando si esegue una scansione senza scambi E' vantaggioso per array quasi ordinati Bubble sort (sol) void bubblesort(int A[], int n){ int scambiato; do{ int i; scambiato=0; for (i = 0; i < n-1; i++) if (A[i] > A[i+1]){ scambiato=1; scambia(&A[i],&A[i+1]); } }while (scambiato); } Ciclo di scansione di elementi consecutivi Bubble sort (sol alt) ● ● ● Al termine della prima scansione l'elemento più grande sarà in fondo all'array In generale, dopo una scansione, dalla posizione dell'ultimo scambio effettuato fino al termine dell'array gli elementi sono ordinati Se si ricorda la posizione dell'ultimo scambio è possibile ridurre il tempo di esecuzione ottenendo un algoritmo più efficiente Bubble sort (sol alt) void bubblesort(int A[], int n){ int scambiato, u=n-1; do{ int i,l; scambiato=0; for (i = 0; i < u; i++) if (A[i] > A[i+1]){ scambiato=1; scambia(&A[i],&A[i+1]); l = i; } u = l+1; }while (scambiato); } Estremo superiore di scansione non più costante ricorda la posizione dello scambio aggiorna l'estremo superiore della scansione Bubble sort: tempo di esecuzione ● ● Il caso peggiore si ha quando gli elementi sono disposti in ordine decrescente. Il numero di operazioni (scambi e confronti) è dato da: iterazione (i) 1 2 3 .. n-1 ● scambi 1 2 3 .. n-1 n−1 2 n⋅n−1 n −n 2 T n=∑ i= = =O n 2 2 1 Se gli elementi sono già ordinati il numero di confronti è pari a n Bubble sort ● ● Si può migliorare ulteriormente l'efficienza del bubble sort effettuando scansioni alternate verso l'alto e verso il basso aggiornando gli estremi della scansione con le posizioni dell'ultimo scambio. Il caso peggiore rimane sempre O(n2) Bubble sort (sol alt) void bubblesort(int A[], int n){ int d, inf, sup, scambiato; d=0; inf=0; sup=n-1; do{ Scansione per indici crescenti ... d=!d; scambiato=0; if (d){ int i, ultimo; for (i=inf; i<sup; i++)7 if (A[i]>A[i+1]){ scambia(&A[i], &A[i+1]); ultimo=i; scambiato=1; } sup=ultimo; }else Variabile per alternare le scansioni Memorizza l'indice dello scambio L'indice dell'ultimo scambio diventa l'estremo superiore per la prossima scansione Bubble sort (sol alt) ... { Scansione per indici decrescenti } int i, ultimo; for (i=sup; i>inf; i--) if (A[i]<A[i-1]){ scambia(&A[i], &A[i-1]); ultimo=i; scambiato=1; } inf=ultimo; Memorizza l'indice dello scambio } }while (scambiato); L'indice dell'ultimo scambio diventa l'estremo inferiore per la prossima scansione