Algoritmo di ordinamento per “scambio” (a bolle o bubble sort) Algoritmo di ordinamento per scambio (a bolle o bubble sort) Per ottenere un ordinamento crescente con l’algoritmo di ordinamento per scambio (bubble sort) si prendono in considerazione i primi due elementi del vettore; se il primo elemento è maggiore del secondo i due elementi vengono scambiati; successivamente si prendono in considerazione il secondo ed il terzo elemento del vettore, si confrontano ed eventualmente si scambiano; questo procedimento si ripete considerando coppie di elementi adiacenti fin quando non si completa tutto il vettore. In questo modo gli elementi maggiori tendono ad andare verso la fine del vettore e i minori tendono ad andare verso l’inizio del vettore. In definitiva l’algoritmo prevede di effettuare più “scansioni” del vettore. Ad ogni scansione si prendono in considerazione una per una tutte le possibili coppie di elementi adiacenti, scambiandoli se sono nell’ordine errato. Al termine della scansione l’elemento minore sarà all’inizio del vettore. Allo stesso modo si può applicare l’algoritmo partendo dalla fine del vettore prendendo in considerazione l’ultimo ed il penultimo elemento confrontandoli ed eventualmente scambiandoli; il procedimento si ripete, come nel caso precedente, considerando coppie di elementi adiacenti fino all’inizio del vettore. Nella versione ottimale dell’algoritmo si controlla se in una scansione avviene o meno uno scambio, se non si verificano scambi il vettore risulta ordinato e, quindi, l’algoritmo termina. Tale versione, ovviamente, è quella più utilizzata in quanto sfrutta il vantaggio dell’algoritmo di terminare nel momento in cui il vettore risulta ordinato. La complessità dell’algoritmo, configurazione iniziale del vettore : nella versione ottimale, dipende dalla Nel caso peggiore, ovvero quando il vettore risulta ordinato in senso decrescente, l’algoritmo richiede un numero di confronti analogo all’algoritmo per sostituzione : (N-1) + (N-2) + (N-3) + ….. +1 = N(N-1)/2 Il caso migliore si verifica quando il vettore è già ordinato. Alla prima passata, con (N-1) confronti, l’algoritmo se ne accorge e non prosegue inutilmente. Il numero di confronti varia quindi fra N(N-1)/2 e (N-1). La prestazione dell’algoritmo è, pertanto, influenzata dalla configurazione iniziale dei dati. “Realizzazione del flow-chart ed implementazione in C++” a cura del Prof. Salvatore DE GIORGI -1- Algoritmo di ordinamento per “scambio” (a bolle o bubble sort) Esempio Dato l’ array : 11 5 3 7 6 4 8 i passi, per un ordinamento crescente, sono i seguenti (in grassetto è indicata la coppia di elementi confrontati ed eventualmente scambiati, la casella evidenziata in giallo è la posizione corrispondente all’elemento minore che sta avanzando verso l’inizio del vettore, le caselle evidenziate in rosso indicano le posizioni del vettore ordinate) : 3 5 11 7 6 4 8 3 5 11 7 4 6 8 3 5 11 4 7 6 8 3 5 4 11 7 6 8 3 4 5 11 7 6 8 3 4 5 11 7 6 8 I passi precedenti, partendo dalla fine del vettore, hanno confrontato le coppie di elementi adiacenti portando nella prima posizione del vettore l’elemento minore (in questo esempio l’elemento minore è già presente l’elemento minore). Successivamente si ripete il procedimento, ripartendo sempre dalla fine, fino alla seconda posizione e così via. Da notare che, nei vari passaggi, anche se nella posizione da ordinare è presente l’elemento minore, si procede, comunque, ad un ordinamento parziale del vettore. Si propone l’esempio solo dei passi per la seconda posizione da ordinare, partendo sempre dalla fine del vettore : 3 4 5 11 7 6 8 3 4 5 11 6 7 8 3 4 5 6 11 7 8 3 4 5 6 11 7 8 e così via… “Realizzazione del flow-chart ed implementazione in C++” a cura del Prof. Salvatore DE GIORGI -2- Algoritmo di ordinamento per “scambio” (a bolle o bubble sort) Per implementare l’Algoritmo si devono usare 2 indici : Uno (I) che tiene conto della posizione in cui si trova l’elemento da ordinare (primo, secondo, terzo, … ) Uno (J) che permette di scorrere l’array dall’inizio o dalla fine e di confrontare gli elementi adiacenti Per la versione ottimale si deve usare una variabile che serve per controllare, ad ogni nuova scansione del vettore, se ci sono stati o meno scambi. Flow chart versione elementare Implementazione in C++, con funzioni, della versione elementare Flow chart versione ottimale partendo dalla fine del vettore Implementazione in C++, con funzioni, della versione ottimale partendo dalla fine Flow chart versione ottimale partendo dall’inizio del vettore Implementazione in C++, con funzioni, della versione ottimale partendo dall’inizio “Realizzazione del flow-chart ed implementazione in C++” a cura del Prof. Salvatore DE GIORGI -3- Algoritmo di ordinamento per “scambio” (a bolle o bubble sort) versione elementare “Realizzazione del flow-chart ed implementazione in C++” a cura del Prof. Salvatore DE GIORGI -4- Algoritmo di ordinamento per “scambio” (a bolle o bubble sort) // ordinamento di un vettore mediante il metodo di scambio //(a bolle o bubble sort) versione elementare #include <iostream> #include <stdlib.h> // per rand() e srand() #include <time.h> // per time() using namespace std; const int maxdim = 100; int dim, pmin; // variabili globali //==================== FUNZIONI ===================== // funzione per la richiesta della dimensione del vettore int dimensione_vettore() { do { cout << "Inserire la dimensione del vettore (max="<<maxdim<<") ..: "; cin >> dim; }while ((dim < 1 ) || (dim > maxdim)); return dim; } // ------------------------------------------// funzione per il caricamento random del vettore void carica_vettore(int v[], int dimvet) { srand (time(NULL)); for (int i = 0; i < dimvet; ++i) {v[i]= rand();} } // ------------------------------------------// funzione per la visualizzazione del vettore void visualizza_vettore(int v[], int dimvet) { cout<<"\n ===== Visualizzazione vettore ====="<<endl; for (int i=0; i < dimvet; ++i) {cout << "\nL'elemento di posto " << i+1 << "...: " << v[i]<<endl;} } //-----------------------------------------------------------// funzione per lo scambio di due variabili void scambia(int &x, int &y) { int temp; temp = x; x = y; y = temp; } “Realizzazione del flow-chart ed implementazione in C++” a cura del Prof. Salvatore DE GIORGI -5- Algoritmo di ordinamento per “scambio” (a bolle o bubble sort) //-------------------------------------------------------------// funzione ordinamento del vettore per scambio (bubble sort) // versione elementare void ordinamento_vettore(int v[], int dimvet) { for (int i = 1 ; i<dim ; ++i ) { for (int j=dim-1; j>=i ; --j ) { if ( v[j-1] > v[j]) { scambia(v[j-1],v[j]); } } } } // ==================== MAIN =========================== int main (int argc, char *argv[]) { char quit; quit = '\0'; int array[maxdim] = {0}; // inizializzazione del vettore while (quit != 'q') { dimensione_vettore(); carica_vettore(array,dim); cout << "\n Vettore caricato : " << endl; visualizza_vettore(array,dim); ordinamento_vettore(array,dim); cout << "\n Vettore ordinato : " <<endl; visualizza_vettore(array,dim); // -----------------------------------------------------------// termine programma con richiesta di uscita cout << "Premere q per uscire "; cin >> quit; } return 0; } “Realizzazione del flow-chart ed implementazione in C++” a cura del Prof. Salvatore DE GIORGI -6- Algoritmo di ordinamento per “scambio” (a bolle o bubble sort) Start richiesta dimensione del vettore Dmax = 100 Dim V I Dim < 2 OR Dim > Dmax F Caricamento vettore Funzione Caricamento vettore Ordinamento vettore Funzione Ordinamento vettore I=0 Visualizzazione vettore F I < Dim End J=0 V V[I] I F=0 I=I+1 I = Dim - 1 Return V[I] < V[I-1] F V C = V[I] V[I] =V[I-1] V[I-1] = C Funzione Visualizzazione vettore F=1 I=0 I=I-1 V F I < Dim V I≠ J V[I] F O J=J+1 I=I+1 V F=1 AND J≠(Dim -1) F Return Return versione ottimale partendo dalla fine del vettore “Realizzazione del flow-chart ed implementazione in C++” a cura del Prof. Salvatore DE GIORGI -7- Algoritmo di ordinamento per “scambio” (a bolle o bubble sort) // ordinamento di un vettore mediante il metodo di scambio //(a bolle o bubble sort) versione ottimale partendo dalla fine #include <iostream> #include <stdlib.h> // per rand() e srand() #include <time.h> // per time() using namespace std; const int maxdim = 100; int dim, pmin; // variabili globali //==================== FUNZIONI ===================== // funzione per la richiesta della dimensione del vettore int dimensione_vettore() { do { cout << "Inserire la dimensione del vettore (max="<<maxdim<<") ..: "; cin >> dim; }while ((dim < 1 ) || (dim > maxdim)); return dim; } // ------------------------------------------// funzione per il caricamento random del vettore void carica_vettore(int v[], int dimvet) { srand (time(NULL)); for (int i = 0; i < dimvet; ++i) {v[i]= rand();} } // ------------------------------------------// funzione per la visualizzazione del vettore void visualizza_vettore(int v[], int dimvet) { cout<<"\n ===== Visualizzazione vettore ====="<<endl; for (int i=0; i < dimvet; ++i) {cout << "\nL'elemento di posto " << i+1 << "...: " << v[i]<<endl;} } //-----------------------------------------------------------// funzione per lo scambio di due variabili void scambia(int &x, int &y) { int temp; temp = x; x = y; y = temp; } “Realizzazione del flow-chart ed implementazione in C++” a cura del Prof. Salvatore DE GIORGI -8- Algoritmo di ordinamento per “scambio” (a bolle o bubble sort) //-------------------------------------------------------------// funzione ordinamento del vettore per scambio (bubble sort) // partendo dalla fine del vettore void ordinamento_vettore(int v[], int dim) { bool scambio; int i,j; j = 0; do { scambio = false; i = dim-1; do { if (v[i] < v[i-1]) { scambia(v[i],v[i-1]); scambio = true; } --i; } while (i != j ); ++j ; } while (scambio == true && j != dim-1) ; return; } // ==================== MAIN =========================== int main (int argc, char *argv[]) { char quit; quit = '\0'; int array[maxdim] = {0}; // inizializzazione del vettore while (quit != 'q') { dimensione_vettore(); carica_vettore(array,dim); cout << "\n Vettore caricato : " << endl; visualizza_vettore(array,dim); ordinamento_vettore(array,dim); cout << "\n Vettore ordinato : " <<endl; visualizza_vettore(array,dim); // -----------------------------------------------------------// termine programma con richiesta di uscita cout << "Premere q per uscire "; cin >> quit; } return 0; } “Realizzazione del flow-chart ed implementazione in C++” a cura del Prof. Salvatore DE GIORGI -9- Algoritmo di ordinamento per “scambio” (a bolle o bubble sort) Start richiesta dimensione del vettore Dmax = 100 Dim V I Dim < 2 OR Dim > Dmax F Caricamento vettore Funzione Caricamento vettore Ordinamento vettore Funzione Ordinamento vettore I=0 Visualizzazione vettore F I < Dim End J=1 V V[I] F=0 I I=I+1 I=0 Return V[I] > V[I+1] F V C = V[I] V[I] =V[I+1] V[I+1] = C Funzione Visualizzazione vettore F=1 I=0 I=I+1 F I < Dim V I < Dim - J F V V[I] O J=J+1 V I=I+1 F=1 AND J ≤ (Dim -1) F Return Return versione ottimale partendo dall’inizio del vettore “Realizzazione del flow-chart ed implementazione in C++” a cura del Prof. Salvatore DE GIORGI -10- Algoritmo di ordinamento per “scambio” (a bolle o bubble sort) // ordinamento di un vettore mediante il metodo di scambio //(a bolle o bubble sort) versione ottimale partendo dall’inizio #include <iostream> #include <stdlib.h> // per rand() e srand() #include <time.h> // per time() using namespace std; const int maxdim = 100; int dim, pmin; // variabili globali //==================== FUNZIONI ===================== // funzione per la richiesta della dimensione del vettore int dimensione_vettore() { do { cout << "Inserire la dimensione del vettore (max="<<maxdim<<") ..: "; cin >> dim; }while ((dim < 1 ) || (dim > maxdim)); return dim; } // ------------------------------------------// funzione per il caricamento random del vettore void carica_vettore(int v[], int dimvet) { srand (time(NULL)); for (int i = 0; i < dimvet; ++i) {v[i]= rand();} } // ------------------------------------------// funzione per la visualizzazione del vettore void visualizza_vettore(int v[], int dimvet) { cout<<"\n ===== Visualizzazione vettore ====="<<endl; for (int i=0; i < dimvet; ++i) {cout << "\nL'elemento di posto " << i+1 << "...: " << v[i]<<endl;} } //-----------------------------------------------------------// funzione per lo scambio di due variabili void scambia(int &x, int &y) { int temp; temp = x; x = y; y = temp; } “Realizzazione del flow-chart ed implementazione in C++” a cura del Prof. Salvatore DE GIORGI -11- Algoritmo di ordinamento per “scambio” (a bolle o bubble sort) //-------------------------------------------------------------// funzione ordinamento del vettore per scambio (bubble sort) // partendo dall’inizio del vettore void ordinamento_vettore(int v[], int dim) { bool scambio; int i,j; j = 1; do { scambio = false; i = 0; do { if (v[i] > v[i+1]) { scambia(v[i],v[i+1]); scambio = true; } ++i; } while (i < dim-j ); ++j ; } while (scambio == true && j <= dim-1) ; }// ==================== MAIN =========================== int main (int argc, char *argv[]) { char quit; quit = '\0'; int array[maxdim] = {0}; // inizializzazione del vettore while (quit != 'q') { dimensione_vettore(); carica_vettore(array,dim); cout << "\n Vettore caricato : " << endl; visualizza_vettore(array,dim); ordinamento_vettore(array,dim); cout << "\n Vettore ordinato : " <<endl; visualizza_vettore(array,dim); // -----------------------------------------------------------// termine programma con richiesta di uscita cout << "Premere q per uscire "; cin >> quit; } return 0; } “Realizzazione del flow-chart ed implementazione in C++” a cura del Prof. Salvatore DE GIORGI -12-