La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

PROGRAMMI DI RICERCA E ORDINAMENTO Ricerca lineare. Abbiamo già visto lalgoritmo che esegue la ricerca lineare di un elemento (detto chiave) in una lista.

Presentazioni simili


Presentazione sul tema: "PROGRAMMI DI RICERCA E ORDINAMENTO Ricerca lineare. Abbiamo già visto lalgoritmo che esegue la ricerca lineare di un elemento (detto chiave) in una lista."— Transcript della presentazione:

1 PROGRAMMI DI RICERCA E ORDINAMENTO Ricerca lineare. Abbiamo già visto lalgoritmo che esegue la ricerca lineare di un elemento (detto chiave) in una lista o vettore, e il corrispondente diagramma di flusso:

2

3 ricercaLin(int elem[], int dim, int chiave) { int indice, trovato, i; trovato = FALSO; indice = -1; i = 0; while (i

4 Osserviamo che il ciclo while è usato per accedere a ciascun elemento del vettore, dal primo allultimo, fino a che si trova una corrispondenza con la chiave desiderata. In tale caso la variabile trovato viene impostata a VERO, il che fa terminare il ciclo; altrimenti la ricerca continua fino a che sincontra la fine del vettore. Per provare questa funzione, scriviamo una funzione pilota main() che chiami ricercaLin e visualizzi il risultato da essa fornito. Il programma completo è il seguente:

5 #include #define VERO 1 #define FALSO 0 #define N 10 void main(void) { int a[N] = {5,10,22,32,45,67,73,98,99,101}; int voce, posto; int ricercaLin(int [], int, int); printf(Scrivi la voce da cercare: ); scanf(%d, &voce); posto = ricercaLin(a, N, voce); if (posto > -1) printf(La voce è stata trovata al posto n° %d\n, posto+1); else printf(La voce non è stata trovata); } ricercaLin(int elem[], int dim, int chiave) { int indice, trovato, i; trovato = FALSO; indice = -1; i = 0; while (i

6 Ricerca binaria. Ricordiamo che la ricerca binaria va eseguita su un vettore ordinato, e che la sua strategia è la seguente: a) si confronta la chiave con lelemento centrale del vettore; a1) se la chiave è uguale allelemento centrale, la ricerca termina con successo; a2) se la chiave è maggiore dellelemento centrale essa, se è presente, si deve trovare nella parte superiore del vettore, e la ricerca continua in essa; a3) se la chiave è minore dellelemento centrale essa, se è presente, si deve trovare nella parte inferiore del vettore, e la ricerca continua in essa.

7 poni trovato = FALSO poni indice = -1 poni indice inferiore = 0 poni indice superiore = dimensione del vettore -1 comincia con il primo elemento while indice infer. <= indice super. AND non si è ancora trovata la chiave poni indice medio = media degli indici infer. e super. if la chiave è uguale allelemento di indice medio la chiave è stata trovata altrimenti, se la chiave è > dellelemento di indice medio poni indice inferiore = indice medio +1 altrimenti, se la chiave è < dellelemento di indice medio poni indice superiore = indice medio -1 fine dellif fine del while fornisci il valore di indice; Come abbiamo visto, lo pseudocodice che implementa questa strategia è: Ed ecco la versione in C di questo pseudocodice:

8 ricercaBin(int elem[], int dim, int chiave) { int indice, trovato, inf, sup, medio; indice = -1; trovato = FALSO; inf = 0; sup = dim -1; while (inf <= sup && !trovato) { medio = (int) ((inf + sup)/2); if (chiave == elem[medio]) { trovato = VERO; indice = medio; } else if (chiave > elem[medio]) inf = medio + 1; else sup = medio - 1; } return(indice); }

9 La precedente funzione ricercaBin andrà poi scritta dopo la seguente funzione principale: #include #define VERO 1 #define FALSO 0 #define N 10 void main(void) { int a[N] = {5,10,22,32,45,67,73,98,99,101}; int voce, posto; int ricercaBin(int [], int, int); printf(Scrivi la voce da cercare: ); scanf(%d, &voce); posto = ricercaBin(a, N, voce); if (posto > -1) printf(La voce è stata trovata al posto n° %d\n, posto+1); else printf(La voce non è stata trovata); }

10 Osserviamo che questa funzione main() usata per la ricerca binaria è la stessa già usata per la ricerca lineare (a parte, ovviamente, il diverso nome di funzione usato nelle due istruzioni che dichiarano e chiamano la funzione).

11 Ordinamento a bolle. Traduciamo ora in programmi C i vari algoritmi di ordinamento già visti. Cominciamo da quello a bolle, che si basa sul seguente algoritmo: a) si confronta ciascun elemento, dal secondo allultimo, con il precedente, e si scambiano se necessario; b) si ripetono i confronti come prima, fermandosi la seconda volta al penultimo elemento, la terza volta al terzultimo,..., lultima volta al secondo elemento. Perciò, nel caso di un vettore con 10 elementi, si inizia confrontando a[1] con a[0], poi a[2] con a[1],... fino ad a[9] con a[8], eseguendo gli scambi necessari. A causa del modo con cui si effettuano i confronti e gli scambi, dopo la prima scansione del vettore ( i = 0 ) il valore più grande sarà memorizzato nellultima componente del vettore (cioè in a[9] ). Per questa ragione la seconda scansione ( i = 1 ), partendo sempre dal confronto di a[1] con a[0], termina al confronto di a[8] con a[7], lasciando in a[8] il secondo valore più grande.

12 In tal modo saranno eseguite in tutto 9 scansioni, al termine delle quali il 9° valore in ordine di grandezza sarà memorizzato in a[1], mentre il più piccolo si troverà in a[0]. Pertanto, nel caso di un vettore a n dimensioni, questo algoritmo esegue n - 1 passate del vettore, mentre il numero di scambi eseguiti dipende dal grado di disordine del vettore (è 0 se il vettore è già ordinato). Lo pseudo codice è quindi il seguente: (in questa fase, le istruzioni indicate in colore non sono strettamente necessarie): poni un contatore di scambi = 0 for lindice i che va dal 1° elemento al penultimo for lindice j che va dal 2° elemento allultimo if num[j] < num[j-1] scambia num[j] con num[j-1] incrementa il contatore di scambi fine del for restituisci il contatore di scambi

13 int ord_bolle(int a[], int numel) { int i, j, temp, scambi = 0; for (i = 0; i < numel - 1; i++) { for (j = 1; j < numel - i; j++) { if (a[j] < a[j-1]) { temp = a[j]; a[j] = a[j-1]; a[j-1] = temp; scambi++; } return(scambi); } Esso si traduce nella seguente funzione:

14 che va scritta dopo la seguente funzione principale: #include #define N 10 void main(void) { int a[N] = {22,5,67,98,45,32,101,99,73,10}; int i, passi; printf("Il vettore ordinato in ordine crescente è:\n"); for (i = 0; i < N; ++i) printf("%d ", a[i]); printf(\n Sono stati eseguiti %d scambi, passi); } int ord_bolle(int [], int); /* prototipo */ passi = ord_bolle(a, N); /* chiamata */

15 Bolle migliorato. Allalgoritmo a bolle si può apportare un sostanziale miglioramento modificandolo come segue: a) si confronta ciascun elemento, dal secondo allultimo, con il precedente, e si scambiano se necessario; In tale modo il numero di passate da eseguire nel vettore non è più fisso (e uguale a n-1 ), ma varia da 1 (nel caso il vettore sia già ordinato) a n-1 (nel caso il vettore abbia il massimo grado di disordine, ossia sia ordinato in senso decrescente). La funzione che apporta questo miglioramento (e che va scritta dopo la funzione principale appena vista) è la seguente: b) si ripete il procedimento fino a quando si esegue una scansione della lista senza effettuare alcuno scambio (perché in tale caso tutti gli elementi sono nellordine corretto).

16 int ord_bolle(int a[], int numel) { int i, j, temp, passi; i = 0; do { passi = 0; for (j=1; j

17 Ordinamento per selezione Vediamo ora il programma dellordinamento per selezione, che si basa sul seguente algoritmo: 1. si seleziona inizialmente il più piccolo tra gli elementi a[1],..., a[n] (o uno dei più piccoli, se ve ne sono più uguali) e lo si scambia con a[1] ; 2. tra gli elementi a[2],..., a[n] del vettore così modificato si seleziona il successivo elemento più piccolo e lo si scambia con a[2], e così si prosegue. 3. Si continua così fino alla iterazione n-1- esima, dopo la quale tutto il vettore a risulta ordinato. Ricordiamo che lo pseudo codice di questo algoritmo è il seguente:

18 for ogni elemento, dal primo al penultimo trova il più piccolo elemento, dal corrente allultimo: ponendo il valore minimo uguale allelemento corrente; salvando lindice dellelemento corrente; for ogni elemento, dal corrente +1 fino allultimo if elemento[indice ciclo interno] < valore minimo poni valore minimo = elemento[indice ciclo interno] salva lindice del nuovo valore minimo trovato fine dellif fine del for scambia il valore corrente con il nuovo valore minimo fine del for Questo pseudo codice esegue lordinamento tramite due cicli for nidificati: Il ciclo esterno determina n – 1 passate attraverso il vettore; in ognuna di esse alla variabile min è inizialmente assegnato il valore num[i], dove i è la variabile contatore del ciclo for esterno. Dato che i comincia da 0 e termina a n - 1, ogni elemento del vettore, tranne lultimo, viene successivamente designato come quello corrente.

19 Il ciclo interno percorre ciclicamente gli elementi successivi a quello corrente per selezionare il prossimo valore più piccolo, cominciando dal valore dellindice i+1 e continuando fino alla fine. Quando viene trovato un nuovo minimo, il suo valore e la sua posizione nel vettore sono memorizzati rispettivamente nelle variabili min e indmin. Una volta completato il ciclo interno, si effettua uno scambio solo se è stato trovato un valore minore di quello nella posizione corrente. Lo pseudo codice si traduce nella seguente funzione ordi_sele :

20 int ordi_sele(int num[], int dim) { int i, j, min, indmin, temp; for (i = 0; i < (dim-1); i++) { min = num[i]; indmin = i; for (j = i+1; j < dim; j++) { if (num[j] < min) { min = num[j]; indmin = j; } if (min < num[i]) { temp = num[i]; num[i] = min; num[indmin] = temp; }

21 #include #define N 10 void main(void) { int a[N] = {22,5,67,98,45,32,101,99,73,10}; int i; int ordi_sele(int [], int); ordi_sele(a, N); printf("Il vettore ordinato in ordine crescente è:\n"); for (i = 0; i < N; ++i) printf("%d ", a[i]); } Si tratta della stessa funzione impiegata per lordinamento a bolle (a parte lovvia differenza del nome della funzione chiamata). Essa si aspetta due argomenti: il vettore da ordinare (ossia lindirizzo del suo primo elemento) il numero dei suoi elementi e va scritta dopo la seguente funzione principale:


Scaricare ppt "PROGRAMMI DI RICERCA E ORDINAMENTO Ricerca lineare. Abbiamo già visto lalgoritmo che esegue la ricerca lineare di un elemento (detto chiave) in una lista."

Presentazioni simili


Annunci Google