Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un...

31
Algoritmi Algoritmi notevoli notevoli In linguaggio C In linguaggio C

Transcript of Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un...

Page 1: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Algoritmi notevoliAlgoritmi notevoliIn linguaggio CIn linguaggio C

Page 2: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

AlgoritmiAlgoritmiRicerca Ricerca (verificare la presenza di un valore in un array)(verificare la presenza di un valore in un array)

Ricerca sequenziale (array non ordinato)Ricerca sequenziale (array non ordinato)Ricerca sequenziale (array ordinato)Ricerca sequenziale (array ordinato)Ricerca binaria (array ordinato)Ricerca binaria (array ordinato)

Ordinamento Ordinamento (ordinare i valori all’interno di un array in modo (ordinare i valori all’interno di un array in modo crescente o decrescente)crescente o decrescente)

Stupid SortStupid SortSelection SortSelection SortBubble SortBubble Sort

MergeMerge(fondere due array ordinati in un terzo array)(fondere due array ordinati in un terzo array)

Page 3: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Algoritmi di Algoritmi di ricercaricerca

In generale un algoritmo di ricerca si pone In generale un algoritmo di ricerca si pone come obiettivo quelli di trovare un come obiettivo quelli di trovare un elemento avente determinate elemento avente determinate caratteristiche all'interno di un insieme di caratteristiche all'interno di un insieme di elementi.elementi.

Nel nostro caso definiremo algoritmi che Nel nostro caso definiremo algoritmi che verificano la presenza di un valore in un verificano la presenza di un valore in un array.array.

L’array può essere non ordinato o ordinato L’array può essere non ordinato o ordinato (ipotizziamo l’ordinamento crescente)(ipotizziamo l’ordinamento crescente)

Page 4: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Ricerca Ricerca sequenzialesequenziale

La ricerca sequenziale (o completa) consiste La ricerca sequenziale (o completa) consiste nella scansione sequenziale degli elementi dal nella scansione sequenziale degli elementi dal primo all’ultimo e si interrompe quando il valore primo all’ultimo e si interrompe quando il valore cercato è stato trovato, oppure quando si è cercato è stato trovato, oppure quando si è sicuri che il valore non può essere presente. sicuri che il valore non può essere presente.

Ha il vantaggio di poter essere applicata anche Ha il vantaggio di poter essere applicata anche a dati non ordinati. a dati non ordinati.

Negli esempi tratteremo la ricerca del valore x Negli esempi tratteremo la ricerca del valore x in un array double di nome v con n elementi con in un array double di nome v con n elementi con funzioni che restituiscono l’indice dell’elemento funzioni che restituiscono l’indice dell’elemento dell’array con valore x o -1 in caso di valore non dell’array con valore x o -1 in caso di valore non trovato.trovato.

Page 5: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Ricerca Ricerca sequenziale in Csequenziale in C

int ricercaSequenziale(double v[], int n, double x) int ricercaSequenziale(double v[], int n, double x)

{ {

int i=0;int i=0;

while (i<n && x!=v[i])while (i<n && x!=v[i])

i++;i++;

if (i>=n)if (i>=n)

return -1;return -1;

return i;return i;

}}

Page 6: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Ricerca Ricerca sequenziale in sequenziale in array ordinatoarray ordinatoint ricercaSequenziale(double v[], int n, double x) int ricercaSequenziale(double v[], int n, double x)

{ {

int i=0;int i=0;

while (i<n && x<v[i])while (i<n && x<v[i])

i++;i++;

if (i<n && v[i]==x)if (i<n && v[i]==x)

return i;return i;

return -1;return -1;

}}

Page 7: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Ricerca binaria o Ricerca binaria o logaritmicalogaritmica

L'algoritmo è simile al metodo usato per trovare una parola L'algoritmo è simile al metodo usato per trovare una parola sul dizionario: sapendo che il vocabolario è ordinato sul dizionario: sapendo che il vocabolario è ordinato alfabeticamente, l'idea è quella di iniziare la ricerca non dal alfabeticamente, l'idea è quella di iniziare la ricerca non dal primo elemento, ma da quello centrale, cioè a metà del primo elemento, ma da quello centrale, cioè a metà del dizionario. A questo punto il valore ricercato viene dizionario. A questo punto il valore ricercato viene confrontato con il valore dell'elemento preso in esame:confrontato con il valore dell'elemento preso in esame:

se corrisponde, la ricerca termina indicando che l'elemento è se corrisponde, la ricerca termina indicando che l'elemento è stato trovato;stato trovato;

se è inferiore, la ricerca viene ripetuta sugli elementi se è inferiore, la ricerca viene ripetuta sugli elementi precedenti (ovvero sulla prima metà del dizionario), precedenti (ovvero sulla prima metà del dizionario), scartando quelli successivi;scartando quelli successivi;

se invece è superiore, la ricerca viene ripetuta sugli elementi se invece è superiore, la ricerca viene ripetuta sugli elementi successivi (ovvero sulla seconda metà del dizionario), successivi (ovvero sulla seconda metà del dizionario), scartando quelli precedenti;scartando quelli precedenti;

se tutti gli elementi sono stati scartati, la ricerca termina se tutti gli elementi sono stati scartati, la ricerca termina indicando che il valore non è stato trovato.indicando che il valore non è stato trovato.

Page 8: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Ricerca binaria in Ricerca binaria in CC

int ricercaBinaria(double v[], int n, double x) { int primo,ultimo,medio; primo = 0; ultimo = n-1; while(primo<=ultimo) // non tutti gli elementi sono stati scartati { medio = (primo+ultimo)/2; if(v[medio]==x) return medio; // valore x trovato alla posizione medio if(v[m]<x) primo = medio+1; // scarto la prima metà else ultimo = medio-1; // scarto la seconda metà } // se il programma arriva qui l’elemento non e’ stato trovato // e sono stati scartati tutti gli elementi return -1; }

Page 9: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Ricerca binaria Ricerca binaria ricorsivaricorsiva

L’algoritmo si presta ad una definizione L’algoritmo si presta ad una definizione ricorsiva.ricorsiva.

Ad ogni chiamata della funzione si verifica Ad ogni chiamata della funzione si verifica se l’elemento ricercato si trova al centro se l’elemento ricercato si trova al centro dell’intervallo e in tal caso la funzione dell’intervallo e in tal caso la funzione termina con successo, in caso contrario si termina con successo, in caso contrario si modifica l’intervallo di ricerca e si effettua modifica l’intervallo di ricerca e si effettua una nuova chiamata della funzione.una nuova chiamata della funzione.

Nel caso in cui l’intervallo di ricerca sia nullo Nel caso in cui l’intervallo di ricerca sia nullo si termina la ricorsione con insuccesso.si termina la ricorsione con insuccesso.

Page 10: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Implementazione Implementazione ricorsivaricorsiva

int ricercaRicorsiva(double v[], int inizio, int fine, double x)

{

if(inizio>fine) // terminazione con insuccesso

return -1;

int medio=(inizio+fine)/2;

if (v[m]==x) // terminazione con successo

return medio;

if (v[m]>x)

return ricercaRicorsiva(v,inizio,medio-1,x);

else

return ricercaRicorsiva(v,medio+1,fine,x);

}

Page 11: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Confronto fra gli Confronto fra gli algoritmialgoritmi

In genere l’efficienza si misura in base In genere l’efficienza si misura in base al numero di confronti effettuati che al numero di confronti effettuati che dipende da n (lunghezza dell’array).dipende da n (lunghezza dell’array).

Si individuano il caso migliore e Si individuano il caso migliore e peggiore ma in generale interessa il peggiore ma in generale interessa il caso medio.caso medio.

Algoritmo Caso migliore

Caso peggiore

Caso medio

Caso medio con n = 1000

Ricerca Sequenziale

1 n n / 2 500

Ricerca Binaria

1 lg2 n lg2 n 10

Page 12: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Algoritmi di Algoritmi di ordinamentoordinamento

Page 13: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Alcuni algoritmiAlcuni algoritmiStupid SortStupid Sort

particolarmente inefficiente, come si può intuire dal particolarmente inefficiente, come si può intuire dal nome. Consiste nel mischiare in qualche modo gli nome. Consiste nel mischiare in qualche modo gli elementi dell’array poi controllare se è ordinato e, elementi dell’array poi controllare se è ordinato e, se non lo è, ricominciare da capo. se non lo è, ricominciare da capo.

Selection SortSelection Sortconsiste in più scansioni dell’array: al termine della consiste in più scansioni dell’array: al termine della prima il primo elemento conterrà il valore minore, prima il primo elemento conterrà il valore minore, poi si proseguirà ordinando la parte successiva poi si proseguirà ordinando la parte successiva dell’array.dell’array.

Bubble SortBubble Sortconsiste nella scansione dell’array elemento per consiste nella scansione dell’array elemento per elemento, scambiando i valori dei due elementi elemento, scambiando i valori dei due elementi consecutivi, quando il primo è maggiore del consecutivi, quando il primo è maggiore del secondo. secondo.

Page 14: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Scambio di Scambio di elementielementi

Tutti gli algoritmi di ordinamento si Tutti gli algoritmi di ordinamento si basano sullo scambio degli elementi basano sullo scambio degli elementi dell’array.dell’array.

In tutti gli esempi faremo riferimento In tutti gli esempi faremo riferimento nelle funzioni a un generico array di nelle funzioni a un generico array di double double vv di lunghezza di lunghezza nn..

Per lo scambio del valore di due Per lo scambio del valore di due elementi useremo la funzione:elementi useremo la funzione:

void scambia(double *e1,double *e2){ double app; // appoggio app = *e1; *e1 = *e2; *e2 = app;}

Page 15: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Stupid sortStupid sortL’algoritmo è probabilistico. L’algoritmo è probabilistico.

La ragione per cui l'algoritmo arriva quasi La ragione per cui l'algoritmo arriva quasi sicuramente a una conclusione è spiegato dal sicuramente a una conclusione è spiegato dal teorema della scimmia instancabile: ad ogni teorema della scimmia instancabile: ad ogni tentativo c'è una probabilità di ottenere tentativo c'è una probabilità di ottenere l'ordinamento giusto, quindi dato un numero l'ordinamento giusto, quindi dato un numero illimitato di tentativi, infine dovrebbe avere illimitato di tentativi, infine dovrebbe avere successo.successo.

Il Bozo Sort è una variante ancora meno efficiente. Il Bozo Sort è una variante ancora meno efficiente. Consiste nel controllare se l'array è ordinato e, se Consiste nel controllare se l'array è ordinato e, se non lo è, prendere due elementi casualmente e non lo è, prendere due elementi casualmente e scambiarli (indipendentemente dal fatto che lo scambiarli (indipendentemente dal fatto che lo scambio aiuti l'ordinamento o meno).scambio aiuti l'ordinamento o meno).

Page 16: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Bozo Sort in CBozo Sort in C void bozoSort(double v[], int n){ while(ordinato(v,n)!=1) mescola(v,n); }

int ordinato(double v[],int n){ int i; // indice array for(i=0;i<n-1;i++) if(v[i]>v[i+1]) return 0; //non ordinato return 1; //ordinato}

void mescola(double v[], int n){ int i1,i2 // indici casuali i1=(rand() % n); i2=(rand() % n); scambia(&v[i1], &v[i2]);}

Page 17: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Selection SortSelection SortL’algoritmo ricerca l’elemento minore L’algoritmo ricerca l’elemento minore della regione del vettore da ordinare e della regione del vettore da ordinare e lo sposta all’inizio della regione stessa.lo sposta all’inizio della regione stessa.

Ad ogni scansione viene spostato un Ad ogni scansione viene spostato un elemento del vettore nella posizione elemento del vettore nella posizione corretta.corretta.

L’ordinamento ha termine quando la L’ordinamento ha termine quando la regione considerata è costituita da un regione considerata è costituita da un solo elemento.solo elemento.

Page 18: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

1 23 4 -56 65 21 32 15 0 -3

-56 23 4 1 65 21 32 15 0 -3

-56 -3 4 1 65 21 32 15 0 23

-56 -3 0 1 65 21 32 15 4 23

-56 -3 0 1 65 21 32 15 4 23

-56 -3 0 1 4 21 32 15 65 23

-56 -3 0 1 4 15 32 21 65 23

-56 -3 0 1 4 15 21 32 65 23

-56 -3 0 1 4 15 21 23 65 32

-56 -3 0 1 4 15 21 23 32 65

Array di partenza

Scansione 1

Scansione 2

Scansione 3

Scansione 4

Scansione 5

Scansione 6

Scansione 7

Scansione 8

Scansione 9

Un esempioUn esempio

Page 19: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Selection Sort in Selection Sort in C (1)C (1)

void selectionSort(double v[],int n) {int s; //scansioniint i; //indice arrayfor (s = 0; s < n - 1; s++) { // n-1 scansioni (n è la dimensione dell’array) for (i = s + 1; i < n; i++) { // scambio di posizione fra il primo elemento // della sequenza e un elemento con valore minore if (v[i] < v[s]) { scambia(&v[i],&v[s]); } } // fine ciclo interno

}}

Page 20: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Selection Sort in Selection Sort in C (2)C (2)

void selectionSort(double v[],int n) { int s; //scansioni int i; //indice array

for (s = 0; s < n - 1; s++){ // n-1 scansioni (n è la dimensione dell’array) // la posizione dell’elemento minore è inizialmente // la prima della regione da analizzare int posizMin = s; for (i = s + 1; i < n; i++) { // ricerca la posizione dell’elemento minore // fra quelli presenti nella regione if (v[i] < v[posizMin]) posizMin = i; } scambia(&v[s],&v[posizMin]);}

}

Page 21: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Bubble SortBubble SortConsiste nella scansione dell’array elemento per Consiste nella scansione dell’array elemento per elemento, scambiando i valori dei due elementi elemento, scambiando i valori dei due elementi consecutivi, quando il primo è maggiore del secondo. consecutivi, quando il primo è maggiore del secondo.

Al termine della scansione, in genere l’array non Al termine della scansione, in genere l’array non risulta ordinato e si deve procedere a una nuova risulta ordinato e si deve procedere a una nuova scansione e alla conseguente serie di eventuali scansione e alla conseguente serie di eventuali scambi tra i valori di due elementi consecutivi.scambi tra i valori di due elementi consecutivi.

Sicuramente l’array risulta ordinato quando si sono Sicuramente l’array risulta ordinato quando si sono effettuate n – 1 scansioni, se n sono gli elementi effettuate n – 1 scansioni, se n sono gli elementi dell’array.dell’array.

E’ detto bubblesort (ordinamento a bolle) per analogia E’ detto bubblesort (ordinamento a bolle) per analogia con le bolle d’aria nell’acqua che, essendo leggere, con le bolle d’aria nell’acqua che, essendo leggere, tendono a spostarsi verso l’alto. tendono a spostarsi verso l’alto.

Page 22: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Un esempioUn esempio

Page 23: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Bubble Sort in C Bubble Sort in C (1)(1)

void bubbleSort(double v[], int n){

int s,i;

for(s=0;s<n-1;s++)

for(i=0;i<n-1;i++)

if (v[i]>v[i+1])

scambia(&v[i],&v[i+1];

}

Page 24: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Bubble Sort in C Bubble Sort in C (2)(2)

• E’ possibile migliorare l’efficienza dell’algoritmo controllando se sono stati effettuati spostamenti, in caso negativo l’array risulta già ordinato

void bubbleSort(double v[], int n){ int spostamento; int s=0; int i; do { spostamento = 0; //nessuno spsostamento for(i=0;i<n-1;i++)

if (v[i]>v[i+1]) { spostamento = 1; //effettuato uno spostamento

scambia(&v[i],&v[i+1]); } s++; } while (spostamento==1 && s<n-1);}

Page 25: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

MergeMergeFusione di due array ordinatiFusione di due array ordinati

Page 26: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

AlgoritmoAlgoritmoSi parte da due array ordinati Si parte da due array ordinati aa e e bb per per ottenere un terzo array ottenere un terzo array cc ordinato e ordinato e contenente sia i dati presenti in contenente sia i dati presenti in aa che che quelli presenti in quelli presenti in bb..

L’algoritmo prevede la scansione dei L’algoritmo prevede la scansione dei due array con due indici diversi due array con due indici diversi trasferendo in trasferendo in cc l’elemento con valore l’elemento con valore minore.minore.

Page 27: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Passaggio 1Passaggio 1

Page 28: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Passaggio 2Passaggio 2

Page 29: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

Passaggio 3Passaggio 3

Page 30: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

void merge(float a[], int na, float b[], int nb, float c[]){void merge(float a[], int na, float b[], int nb, float c[]){

int i=0,j=0,k=0;int i=0,j=0,k=0;

while (i<na && j<nb) { // né a né b sono «finiti»while (i<na && j<nb) { // né a né b sono «finiti»

if (a[i]<b[j]) {if (a[i]<b[j]) {

c[k]=a[i]; // prendo elemento di ac[k]=a[i]; // prendo elemento di a

i++;i++;

}}

else {else {

c[k]=b[j]; // prendo elemento di bc[k]=b[j]; // prendo elemento di b

j++;j++;

}}

k++;k++;

} // … segue …} // … segue …

Page 31: Algoritmi notevoli In linguaggio C. Algoritmi Ricerca (verificare la presenza di un valore in un array) Ricerca sequenziale (array non ordinato) Ricerca.

… … segueseguewhile (i<na) { // è finito b allora copio il resto di awhile (i<na) { // è finito b allora copio il resto di a

c[k]=a[i];c[k]=a[i];

k++;k++;

i++;i++;

}}

while (j<nb) { // è finito a allora copio il resto di bwhile (j<nb) { // è finito a allora copio il resto di b

c[k]=b[j];c[k]=b[j];

k++;k++;

j++;j++;

}}

} // fine funzione} // fine funzione