Il 0% ha trovato utile questo documento (0 voti)
19 visualizzazioni14 pagine

Ordinamento 2021

Caricato da

yannbouzan2005
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Il 0% ha trovato utile questo documento (0 voti)
19 visualizzazioni14 pagine

Ordinamento 2021

Caricato da

yannbouzan2005
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Sei sulla pagina 1/ 14

ORDINAMENTO DI UN VETTORE

L’ordinamento dei dati è utile


• Per poter ottimizzare le operazioni di ricerca in un array è opportuno
che i dati in esso memorizzati siano ordinati. Infatti, se l'array è
ordinato è possibile usare la tecnica dicotomica.
• Per altre operazioni, quali raggruppamento di dati, calcolo di funzioni
aggregate (medie, conteggi), …

Gli algoritmi di ordinamento che vedremo sono basati sul seguente


schema:

- Per I da 0 a N-2
- Inserisci l’elemento più piccolo tra I e N-1 in posizione I

oppure

- Per I da 0 a N-2
- Inserisci l’elemento più grande tra 0 e N - 1 - I in posizione N - 1 - I

Consideriamo l’azione:

Inserisci l’elemento più grande tra 0 e N - 1 - I in posizione N - 1 - I

Algoritmo Selection Sort:


- Individua la posizione IMAX dell’elemento più grande
tra 0 e N - 1 - I
- Scambia l’elemento in posizione IMAX con quello
in posizione N - 1 - I

Algoritmo Bubble Sort:


- Per ogni elemento tra 0 e N - 1 - I
- Confronta coppie di elementi consecutivi e, se necessario,
scambia gli elementi

ORDINAMENTO DI UN VETTORE 1
ORDINAMENTO CON IL METODO SELECTION SORT
- Per I da 0 a N-2
- Individua la posizione IMAX dell’elemento più grande
tra 0 e N - 1 - I
- Scambia l’elemento in posizione IMAX con quello
in posizione N - 1 - I

#define N 8
#include <stdio.h>

main(){
int IMAX;
int I,J;
int V[N]={3,9,4,7,1,6,8,5}; /* vettore */
int temp;

for(I=0; I<N-1; I++) {


IMAX= N-1-I;
for(J=0; J<N-1-I; J++)
if (V[IMAX]< V[J])
IMAX = J;
temp=V[IMAX];
V[IMAX]=V[N-1-I];
V[N-1-I]=temp;
}
}

La parte a sfondo grigio indica il sotto-array considerato al ciclo i-mo e


l'elemento che viene spostato è sottolineato.
3 9 4 7 1 6 8 5 array iniziale
3 5 4 7 1 6 8 9
3 5 4 7 1 6 8 9
3 5 4 6 1 7 8 9
3 5 4 1 6 7 8 9
3 1 4 5 6 7 8 9
3 1 4 5 6 7 8 9
1 3 4 5 6 7 8 9 array finale

ORDINAMENTO DI UN VETTORE 11
ORDINAMENTO CON IL METODO BUBBLE SORT - 1A VERSIONE
Primo Ciclo esterno:
Con N-1 “scambi” il più grande tra 0 e N-1 è portato in posizione N-1
3 9 4 7 1 6 8 5 array iniziale
3 9 4 7 1 6 8 5 for (J=0;J<N-I-1;J++)
3 4 9 7 1 6 8 5 if (V[J+1]<V[J]){
temp=V[J];
3 4 7 9 1 6 8 5 V[J]=V[J+1];
3 4 7 1 9 6 8 5 V[J+1]=temp;
3 4 7 1 6 9 8 5 }
3 4 7 1 6 8 9 5
3 4 7 1 6 8 5 9

Caso generale - I-esimo Ciclo esterno:


Con N-1-I “scambi” il più grande tra 0 e N-1-I è portato in posizione N-1-I
for (J=0;J<N-I-1;J++)
if (V[J+1]<V[J]){
temp=V[J]; V[J]=V[J+1]; V[J+1]=temp; }

Per Ordinare il vettore occorre fare N-1 cicli esterni :


#define N 8 /* dimensione del vettore */
main(){
int V[N]={3,9,4,7,1,6,8,5}; /* vettore */
int I,J;
int temp;
for (I=0;I<N-1;I++)
for (J=0;J<N-I-1;J++)
if (V[J+1]<V[J]){
temp=V[J];
V[J]=V[J+1];
V[J+1]=temp;
}
}

Risultato al termine di ogni ciclo esterno:

3 9 4 7 1 6 8 5 array iniziale
3 4 7 1 6 8 5 9 dopo primo ciclo con I
3 4 1 6 7 5 8 9 ...
3 1 4 6 5 7 8 9
1 3 4 5 6 7 8 9
1 3 4 5 6 7 8 9
1 3 4 5 6 7 8 9
1 3 4 5 6 7 8 9 array finale

ORDINAMENTO DI UN VETTORE 3
ORDINAMENTO CON IL METODO BUBBLE SORT - 2A VERSIONE
Nell'esempio precedente si vede che le ultime due iterazioni non hanno
effetto, poichè l'array risultava già ordinato alla quarta iterazione. Per
migliorare la prima versione dell'ordinamento bubble è sufficiente
considerare che se durante una iterazione esterna non vengono effettuati
scambi l'array è già ordinato. Si introduce quindi la variabile Scambio per
segnala se non sono avvenuti scambi e quindi il processo di ordinamento
può terminare. La terminazione anticipata può avvenire programmando il
ciclo esterno con while anziché con for.

#define N 8 /* dimensione del vettore */


main(){
int V[N]={3,9,4,7,’1’,6,8,5}; /* vettore */
int I,J;
int temp;
int Scambio;

Scambio =1; /* entra obbl. nel ciclo la prima volta */


I=0;
while (I<N-1 && Scambio==1) {
Scambio =0;
for (J=0;J<N-I-1;J++)
if (V[J+1]<V[J]){
temp=V[J];
V[J]=V[J+1];
V[J+1]=temp;
Scambio=1; /* traccia di scambio avvenuto */
} /* end if */
I++;
} /* end while */
}

Esempio (La parte a sfondo grigio indica il sotto-array considerato al ciclo i-esimo)

3 9 4 7 1 6 8 5 array iniziale
3 4 7 1 6 8 5 9 dopo primo ciclo con j
3 4 1 6 7 5 8 9 ...
3 1 4 6 5 7 8 9
1 3 4 5 6 7 8 9
1 3 4 5 6 7 8 9 array finale

ORDINAMENTO DI UN VETTORE 11
RICERCA DICOTOMICA (O BINARIA)
• La tecnica di ricerca dicotomica può essere utilizzata su un vettore i cui
elementi sono ordinati.

• individuare l'elemento centrale della sequenza e confrontarlo con


l'obiettivo della ricerca: se l'elemento centrale è minore di quest'ultimo si
prosegue la ricerca nella metà superiore della sequenza, altrimenti in
quella inferiore.

• La ricerca si arresta quando l'elemento centrale corrisponde a quello


cercato oppure non ci sono più porzioni di sequenza da esaminare.

• La posizione elemento centrale di una sequenza delimitata dalle


posizioni Inizio e Fine si determina con la formula (Inizio+Fine) / 2

- Inizializza Trovato a zero

- finchè Inizio <= Fine e Trovato è zero


- calcola la posizione centrale C
- se l'elemento di posizione C è uguale a D
poni Trovato uguale a 1
altrimenti
- se l'elemento di posizione C è < di D
- ricerca fra C+1 e Fine
altrimenti
- ricerca fra Inizio e C-1
- se Trovato uguale a 1
la ricerca ha successo (risposta positiva)
altrimenti
la ricerca fallisce (risposta negativa)

ORDINAMENTO DI UN VETTORE 5
#include <stdio.h>
#define N 8
main(){
int V[N] = {1,6,7,13,21,23,34,35}; /* vettore ordinato*/
int D; /* elemento da cercare */
int Inizio,Fine,C;
int Trovato=0;
int I;

printf("elemento da cercare nel vettore ?");


scanf("%d",&D);
/* ricerca binaria iterativa */
Inizio=0;
Fine=N-1;
while ((Inizio<=Fine)&&(Trovato==0)) {
C=(Inizio+Fine)/2;
if (D==V[C])
Trovato=1;
else
if (D>V[C])
Inizio=C+1;
else
Fine=C-1;
}
if (Trovato==1)
printf("L'elemento %d e' nel vettore",D);
else
printf("L'elemento %d non e' nel vettore",D);
}

Esempi (I denota Inizio, F denota Fine)


Ricerca dell’elemento 23
0 1 2 3 4 5 6 7
1 6 7 13 21 23 34 35 array ordinato
I C F Primo passo
I C F Secondo passo à Trovato=1

Ricerca dell’elemento 2
1 6 7 13 21 23 34 35 array ordinato
I C F Primo passo
I C F Secondo passo
I Terzo passo
F
C
F I I > F à Fine cliclo à Trovato=0

ORDINAMENTO DI UN VETTORE 11
ORDINAMENTO DI UN VETTORE: ESERCIZI
Dato un vettore di interi, con valori ripetuti:

1. STAMPA I VALORI DISTINTI (CIOE’ STAMPA IL VETTORE SENZA RIPETIZIONI)

2. CALCOLO DEL NUMERO DI VALORI DISTINTI

3. CALCOLO DELLA FREQUENZA DI OGNI VALORE

4. CALCOLO DELLA MASSIMA FREQUENZA

5. INDIVIDUA VALORI CHE SI RIPETONO PIU’ VOLTE (CIOE’ CON MASSIMA FREQUENZA)

Tutti questi problemi si risolvono ordinando il vettore.

ORDINAMENTO DI UN VETTORE 7
#include <stdio.h>
#define N 8 /* dimensione del vettore */

main(){
int V[N]={2,9,9,7,2,2,8,5}; /* vettore */
int I,J; int temp; int NumeroValoriDistinti; int Frequenza; int MaxFrequenza;

// ORDINAMENTO DEL VETTORE CON BUBBLE SORT


for (I=0;I<N-1;I++)
for (J=0;J<N-I-1;J++)
if (V[J+1]<V[J]){
temp=V[J];
V[J]=V[J+1];
V[J+1]=temp; }

// STAMPA VETTORE ORDINATO


for (I=0;I<N;I++)
printf("%d\n",V[I]);

// CALCOLO DEL NUMERO DI VALORI DISTINTI


NumeroValoriDistinti=0;

for (I=0;I<N;I++)
if (I==N-1 || V[I+1] != V[I])
NumeroValoriDistinti++;

printf("Valori Distinti %d\n",NumeroValoriDistinti);

// CALCOLO DELLA FREQUENZA DI OGNI VALORE - DA COMPLETARE

for (I=0;I<N;I++){

if (I==N-1 || V[I+1] != V[I]){


printf("Valore %d Frequenza %d\n",V[I],Frequenza );

}
}

// CALCOLO DELLA MASSIMA FREQUENZA - DA COMPLETARE


for (I=0;I<N;I++){

if (I==N-1 || V[I+1] != V[I]){

}
}

printf("\nMaxFrequenza=%d\n",MaxFrequenza);

// STAMPA DEI VALORI CHE SI RIPETONO PIU’ VOLTE (CIOE’ CON MASSIMA FREQUENZA) - DA COMPLETARE

for (I=0;I<N;I++){

if (I==N-1 || V[I+1] != V[I]){

}
}
}

ORDINAMENTO DI UN VETTORE 11
SOLUZIONE

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define N 8 /* dimensione del vettore */

main(){
int V[N]={2,9,9,7,2,2,8,5}; /* vettore */
int I,J;
int temp;
int NumeroValoriDistinti;
int Frequenza;
int MaxFrequenza;

// ORDINAMENTO CON BUBBLE SORT

for (I=0;I<N-1;I++)
for (J=0;J<N-I-1;J++)
if (V[J+1]<V[J]){
temp=V[J];
V[J]=V[J+1];
V[J+1]=temp;
}

// STAMPA VETTORE ORDINATO


for (I=0;I<N;I++)
printf("%d\n",V[I]);

// CALCOLO DEL NUMERO DI VALORI DISTINTI

NumeroValoriDistinti=0;

for (I=0;I<N;I++)
if (I==N-1 || V[I+1] != V[I])
NumeroValoriDistinti++;

printf("Valori Distinti %d\n",NumeroValoriDistinti);

// CALCOLO DELLA FREQUENZA DI OGNI VALORE

Frequenza=0;
for (I=0;I<N;I++){
Frequenza++;
if (I==N-1 || V[I+1] != V[I]){
printf("Valore %d Frequenza %d\n",V[I],Frequenza );
Frequenza=0;
}
}

// CALCOLO DELLA MASSIMA FREQUENZA

Frequenza=0;
MaxFrequenza=0;
for (I=0;I<N;I++){
Frequenza++;
if (I==N-1 || V[I+1] != V[I]){
printf("Valore %d Frequenza %d\n",V[I],Frequenza );
if (Frequenza>MaxFrequenza)
MaxFrequenza=Frequenza;
Frequenza=0;
}
ORDINAMENTO DI UN VETTORE 9
}

printf("\nMaxFrequenza=%d\n",MaxFrequenza);

// STAMPA DEI VALORI CHE SI RIPETONO PIU’ VOLTE (CIOE’ CON MASSIMA FREQUENZA)

Frequenza=0;
for (I=0;I<N;I++){
Frequenza++;
if (I==N-1 || V[I+1] != V[I]){
if (Frequenza==MaxFrequenza)
printf("\n Valore %d ha max frequenza\n",V[I]);
Frequenza=0;
}
}

system("PAUSE");
}

ORDINAMENTO DI UN VETTORE 11
/* DATE DUE STRINGHE STABILIRE SE UNA E' L'ANAGRAMMA DELL'ALTRA */

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#define N 8 /* dimensione massima della stringa*/

/* SUGGERIMENTO : SI ORDINANO ENTRAMBRE LE STRINGHE E SI CONFRONTANO */

main(){
char S1[N] = "Tiro";
char S2[N] = "Rito";
int I, J; char temp;

/* CONVERTIRE S1 e S2 in MAIUSCOLO */

for (I = 0; S1[I] != '\0'; I++)


if (S1[I] >= 'a' && S1[I] <= 'z')
S1[I] = S1[I] + ('A' - 'a') ;

printf("\n\n Stringa s1 Maiuscola %s ", S1);

for (I = 0; S2[I] != '\0'; I++)


if (S2[I] >= 'a' && S2[I] <= 'z')
S2[I] = S2[I] + ('A' - 'a');

printf("\n\n Stringa s2 Maiuscola %s ", S2);

/* ordino stringa S1 tramite bubble sort*/


/* strlen calcolo lunghezza di una stringa */

printf("lunghezza %s = %d ", S1, strlen(S1));

for (I = 0; I < strlen(S1) - 1; I++)


for (J = 0; J < strlen(S1) - 1 - I; J++ )
if (S1[J + 1] < S1[J]){
temp = S1[J];
S1[J] = S1[J + 1];
S1[J + 1] = temp;
}

printf("\n\n Stringa s1 Ordinata %s ", S1);

for (I = 0; I < strlen(S2) - 1; I++)


for (J = 0; J < strlen(S2) - 1 - I; J++)
if (S2[J + 1] < S2[J]){
temp = S2[J];
S2[J] = S2[J + 1];
S2[J + 1] = temp;
}

printf("\n\n Stringa s2 Ordinata %s ", S2);

if (strcmp(S1, S2) == 0)
printf("\n\n OK .... una e' l'anagramma dell'altra");

system("PAUSE");
}

ORDINAMENTO DI UN VETTORE 11
VETTORI DI STRINGHE

typedef char TIPOSTRINGA [20];

typedef TIPOSTRINGA TIPOCOGNOMENOME[2];

è un (tipo) vettore con una coppia di stringhe (cioè con due stringhe);

TIPOCOGNOMENOME TIPOSTRINGA TIPOSTRINGA

si ipotizza che
/* l’elemento (stringa) 0 è il cognome, l’elemento (stringa) 1 è il nome */

TIPOCOGNOMENOME PERSONE[N]

è un vettore di N coppie di stringhe

0 TIPOSTRINGA TIPOSTRINGA

1 TIPOSTRINGA TIPOSTRINGA

2 TIPOSTRINGA TIPOSTRINGA


N_1 TIPOSTRINGA TIPOSTRINGA

Dato il vettore PERSONE, ordinarlo alfabeticamente in base al Cognome e quindi in base al


Nome

ORDINAMENTO DI UN VETTORE 11
#include <stdio.h>
#include <string.h>

#define N 5
#define LS 20

main(){
typedef char TIPOSTRINGA [20];
typedef TIPOSTRINGA TIPOCOGNOMENOME[2];
/* l’elemento (stringa) 0 è il cognome, l’elemento (stringa) 1 è il nome */

int I,J;

TIPOSTRINGA ELENCO[N] = { "alba", "albero", "casa", "telefono", "casa" };


TIPOSTRINGA temp;

TIPOCOGNOMENOME PERSONE[N] = { { "Rossi", "Paolo"} , { "Rossi", "Pio"},


{ "Verde", "Paolo"},{ "Bianco", "Ugo"},{ "Bianco", "Pio"} };

TIPOCOGNOMENOME temp2;

for(I=0; I<N; I++)


printf("\n\n %s", ELENCO[I]);

for(I=0; I<N-1; I++)


for(J=0; J<N-1-I; J++)
if (strcmp(ELENCO[J+1],ELENCO[J])<0){
strcpy(temp,ELENCO[J]);
strcpy(ELENCO[J],ELENCO[J+1]);
strcpy(ELENCO[J+1], temp);
}

for(I=0; I<N; I++)


printf("\n\n %s", ELENCO[I]);

printf("\n\n Persone (Cognome e Nome)");

for(I=0; I<N; I++)


printf("\n %-20s %-20s ", PERSONE[I][0] , PERSONE[I][1]);

for(I=0; I<N-1; I++)


for(J=0; J<N-1-I; J++)
if (strcmp(PERSONE[J+1][0],PERSONE[J][0])<0
|| strcmp(PERSONE[J+1][0],PERSONE[J][0])==0 &&
strcmp(PERSONE[J+1][1],PERSONE[J][1])<0 ){
strcpy(temp,PERSONE[J][0]);
strcpy(PERSONE[J][0],PERSONE[J+1][0]);
strcpy(PERSONE[J+1][0], temp);

strcpy(temp,PERSONE[J][1]);
strcpy(PERSONE[J][1],PERSONE[J+1][1]);
strcpy(PERSONE[J+1][1], temp);
}

printf("\n\n Persone (Cognome e Nome)");


for(I=0; I<N; I++)
printf("\n %-20s %-20s ", PERSONE[I][0] , PERSONE[I][1]);

ORDINAMENTO DI UN VETTORE 13
NOTE

E' sbagliato effettuare lo scambio tramite assegnamento, ovvero


temp2=PERSONE[J]);
PERSONE[J]=PERSONE[J+1]);
PERSONE[J+1]= temp2
In quanto temp2 e PERSONE[J] sono vettori!!

Non è possibile neanche fare la copia di PERSONE[J] in temp2 tramite strcpy, cioè se
facciamo

strcpy(temp2, PERSONE[0]);

In temp2 viene copiato solo il contenuto di PERSONE[0] fino al fine stringa, cioè solo il
cognome. Per controllare se stampiamo i due elementi di temp2
printf("\n %-20s %-20s ", temp2[0] ,temp2[1]);

otteniamo

Quindi se facessimo lo scambio in questo modo


strcpy(temp2, PERSONE[1]);
strcpy(PERSONE[1],PERSONE[2] );
strcpy(PERSONE[2], temp2);

Verrebbe fatto solo lo scambio dei cognomi e non dei nomi, come si può verificare
printf("\n %-20s %-20s ", PERSONE[1][0] , PERSONE[1][1]);
printf("\n %-20s %-20s ", PERSONE[2][0] , PERSONE[2][1]);

si ottiene

ORDINAMENTO DI UN VETTORE 11

Potrebbero piacerti anche