420 likes | 542 Views
Corso di Calcolatori Elettronici. APPUNTI SUL LINGUAGGIO C Esercitazione I Esercizi di base. a. b. n1. n2. n3. ni. max. n10. Esercizio: Scrivere un programma per calcolare il massimo tra 10 numeri forniti dall’utente. Pseudocodifica.
E N D
Corso di Calcolatori Elettronici APPUNTI SUL LINGUAGGIO C Esercitazione I Esercizi di base
a b n1 n2 n3 ni max n10 Esercizio: Scrivere un programma per calcolare il massimo tra 10 numeri forniti dall’utente.
Pseudocodifica ► scriviamo una procedura per calcolare il massimo tra due numeri MAX(a,b) if a>b then massimo ← a else massimo ← b return massimo ► scriviamo una procedura che calcola il massimo tra 10 numeri MAXtot() i ← 2 Leggi(a) Leggi(b) massimo ← MAX(a,b) while i < 10 do Leggi(a) massimo ← MAX(massimo,a); i ← i + 1 return massimo
Pseudocodifica ► algoritmo principale begin massimo ← Maxtot() Stampa(massimo) end
Programma C #include <stdio.h> int MAX(int a, int b) { int massimo; if (a>b) massimo=a; else massimo=b; return massimo; } int MAXtot() { int a, i=2, massimo; scanf("%d", &a); scanf("%d", &massimo); massimo = MAX(a,massimo); while (i<10) { printf("Inserire un numero:"); scanf("%d", &a); Massimo = MAX(massimo,a); i++; return massimo; } main() { printf("Il numero massimo inserito e’: %d\n", MAXtot()); }
Array Esercizio: Data una lista di N numeri (un array di N elementi) stampare il minimo e il massimo elemento tra gli N forniti da input. Oss. N sia una costante (per esempio 15).
Pseudocodifica ► scriviamo una procedura per calcolare il massimo in un vettore MAX(vet) max ← vet[0] for i ← 1 to 15 do if vet[i] > max then max = vet[i] return max ► scriviamo una procedura per calcolare il minimo in un vettore MIN(vet) min ← vet[0] for i ← 1 to 15 do if vet[i] < min then min = vet[i] return min
Pseudocodifica ► algoritmo principale begin Leggi(vet) massimo ← MAX(vet) minimo ← MIN(vet) Stampa(minimo) Stampa(massimo) end
Array include <stdio.h>; #define N 15 /* è noto a tutti che la dimensione del vettore è N */ int minimo (int vet[]) { int i, min; min = vet[0]; for (i = 1; i<N; i ++) if (vet[i]<min) min = vet[i]; return min; } int massimo (int vet[]) { int i, max; max = vet[0]; for (i = 1; i<N; i ++) if (vet[i]>max) max = vet[i]; return max; }
Array main () { int i, a[N]; printf ("Scrivi %d numeri interi\n", N); for (i = 0; i<N; i++) scanf ("%d", &a[i]); printf ("Il minimo vale %d e il massimo è %d\n", minimo(a), massimo(a)); }
Array Dati N valori interi forniti in ordine qualunque, stampare in uscita l'elenco dei valori dati in ordine crescente. Oss. N sia una costante (per esempio 15). Vettore di elementi di un certo tipo, sul quale è definita una relazione d’ordine totale : – Selection sort, o ordinamento per minimi successivi: – Ad ogni passo seleziona il minimo nel vettore e lo pone nella prima posizione, richiamandosi ed escludendo dal vettore il primo elemento.
Array Primo livello di specifica: – leggi gli elementi – ordina il vettore – stampa il vettore ordinato • Secondo livello di specifica per l’ordinamento while (<il vettore ha più di una componente>) { <individua il minimo nel vettore corrente in posizione posmin> <scambia se necessario il primo elemento del vettore corrente con quello in posizione posmin > <considera come vettore corrente quello precedente tolto il primo elemento> }
Array posmin [0] [1] [2] [3] 2 5 1 -1 posmin [0] [1] [2] [3] [0] [1] [2] [3] -1 5 1 2 -1 5 1 2 Vettore corrente
Pseudocodifica ► scriviamo una procedura per ordinare un vettore tramite l’insertion sort SORT(vet) for j← 0 to lenght(vet) do posmin ← j min ← vet[j] ► mi calcolo posmin for i ← j to lenght(vet) doif vet[i] < min then min ← vet[i] posmin ← i ► verifico se il posmin è cambiato e quindi scambio if posmin ≠ j then vet[posmin] ← vet[j] vet[j] ← min
Pseudocodifica ► algoritmo principale begin Leggi(vet) SORT(vet) Stampa(vet) end
Array #include <stdio.h> #define N 15 void leggi(int a[]) { int i; printf ("Scrivi %d interi\n", N); for (i = 0; i < N; i++) scanf ("%d", &a[i]); } void scrivi(int a[]) { int i; printf ("Vettore ordinato:\n"); for (i = 0; i < N; i++) printf ("%d \t", a[i]); }
Array void sort (int vet[]) { int j, i, posmin, min; for (j=0; j < N; j++) { posmin=j; min = vet[j]; for (i=j+1;i<N; i++) if (vet[i]<min) { min=vet[i]; posmin=i; } if (posmin != j) { /*scambio */ vet[posmin]=vet[j]; vet[j]= min; } } }
Array main () { int i, a[N]; leggi(a); sort(a); scrivi(a); }
Array Dati N valori interi forniti in ordine qualunque, stampare in uscita l'elenco dei valori dati in ordine crescente. Oss. N sia una costante (per esempio 15). Vettore di elementi di un certo tipo, sul quale è definita una relazione d’ordine totale : – Merge Sort
Merge Sort dividi fondi
Merge Sort • Assumiamo di avere un vettore A • Indichiamo con p e r gli indici di estremo (primo e ultima posizione) • q rappresenta l’indice di pivot per dividere una sequenza • p < q < r • A[p..q] e A[q+1..r] sono ordinati • MERGE(A,p,q,r) per fondere • MERGE-SORT(A,p,r) per ordinare
► scriviamo la procedura di fusione MERGE(A,p,q,r) i ← p j ← q+1 k ← 1 while i<= q and j <= r doif A[i] <= A[j] then APP[k] ← A[i] i ← i + 1 else APP[k] ← A[j] j ← j + 1 k ← k + 1 if i = q+1 thenfor i← j to r do APP[k] ← A[i] k ← k+1 elsefor j← i to q do APP[k] ← A[j] k ← k+1 k ← 1 for i← p to r do A[i] ← APP[k] k ← k + 1
► scriviamo la procedura di ordinamento MERGE-SORT(A,p,r) if p < r then q ← (p+r)/2 MERGE-SORT(A,p,q) MERGE-SORT(A,q+1,r) MERGE(A,p,q,r) ► scriviamo il blocco principale begin Leggi(vet) MERGE-SORT(vet,1,lenght(vet)) Stampa(vet) end
Array #include <stdio.h> #define N 15 void leggi(int a[]) { int i; printf ("Scrivi %d interi\n", N); for (i = 0; i < N; i++) scanf ("%d", &a[i]); } void scrivi(int a[]) { int i; printf ("Vettore ordinato:\n"); for (i = 0; i < N; i++) printf ("%d \t", a[i]); }
void Merge(int A[], int iniziale, int mediano, int finale) { /* Fonde i due sottovettori ordinati di A da iniziale a mediano e da mediano+1 a finale in un unico sottovettore ordinato. */ int B[100]; /* vettore di appoggio */ int primo, secondo, appoggio, da_copiare; primo = iniziale; secondo = mediano + 1; appoggio = iniziale; while (primo <= mediano && secondo <= finale) { if (A[primo] <= A[secondo]) { B[appoggio] = A[primo]; primo++; } else { B[appoggio] = A[secondo]; secondo++; } appoggio++; }
if (secondo > finale) /* e‘ finito prima il secondo sottovettore; copia da A in B tutti gli elementi del primo sottovettore fino a mediano */ for (da_copiare = primo; da_copiare <= mediano; da_copiare++) { B[appoggio] = A[da_copiare]; appoggio++; } else /* e‘ finito prima il primo sottovettore copia da A in B tutti gli elementi del secondo sottovettore fino a finale */ for (da_copiare = secondo; da_copiare <= finale; da_copiare++) { B[appoggio] = A[da_copiare]; appoggio++; } /* ricopia tutti gli elementi da iniziale a finale da B ad A */ for (da_copiare = iniziale; da_copiare <= finale; da_copiare++) A[da_copiare] = B[da_copiare]; } /* MergeVettore */
void MergeSort(int A[], int iniziale, int finale) { /* Ordina gli elementi del vettore A di indice compreso tra iniziale e finale usando l’algoritmo di ordinamento per fusione. */ int mediano; if (iniziale < finale) { /* l’intervallo da iniziale a finale, estremi inclusi comprende almeno due elementi */ mediano = (iniziale + finale) / 2; MergeSort(A, iniziale, mediano); MergeSort(A, mediano+1, finale); Merge(A, iniziale, mediano, finale); } } /* MergeRicorsivo */ main(){ /* Ordina i primi n elementi del vettore A usando l’algoritmo di ordinamento per fusione. */ int A[100]; leggi(A); MergeSort(A, 0, N-1); scrivi(A); } /* MergeSort */
Array Dati N valori interi forniti in ordine qualunque, stampare in uscita l'elenco dei valori dati in ordine crescente. Oss. N sia una costante (per esempio 15). Vettore di elementi di un certo tipo, sul quale è definita una relazione d’ordine parziale : – Heap Sort
Heap Un Heap è un albero bilanciato rappresentato mediante un array. Ad ogni nodo dell’albero è associato un indice 1 : 2 3 4 5 6 7 8 9 10
Heap Un Heap è una struttura dati composta da un array che possiamo considerare come un albero binario quasi completo. Ad ogni nodo dell’albero è associato un indice 1 : 9 2 3 8 7 4 5 6 7 6 2 4 5 8 9 10 5 1 0
Heap in C Utiliziamo una convenzione: • In posizione [0] indichiamo il numero di elementi dell’Heap (hp) • In posizione [N-1] indichiamo la lunghezza N dell’array • PARENT(i), LEFT(i) e RIGHT(i) restituiscono gli indici del padre, figlio sinistro, figlio destro del nodo in posizione i. 1 : 9 2 3 8 7 4 5 6 7 6 2 4 5 8 9 10 5 1 0 10 .. 99
► scriviamo le procedure di navigazione dell’HEAP PARENT(i) return i/2 LEFT(i) return 2i RIGHT(i) return 2i+1
Heapify Due Tipi di HEAP • MAX-HEAP: A[PARENT(i)] > A[i] • MIN-HEAP: A[PARENT(i)] < A[i] Si vuole conservare tale proprietà di HEAP.
► Scriviamo la procedura di MAX-HEAPIFY MAX-HEAPIFY(A,i) l ← LEFT(i) r ← RIGHT(i) if l < A[0] and A[l] > A[i] then massimo ← l else massimo ← i if r < A[0] and A[r] > A[massimo] then massimo ← r if massimo ≠ ithen “scambia A[i] con A[massimo]” MAX-HEAPIFY(A,massimo)
Proprietà che le foglie in un heap partono dall’indice n/2, con n numero di nodi ► Dato un Array qualsiasi vogliamo convertirlo in un MAX-HEAP BUILD-MAXHEAP(A) A[0] ← lenght(A) for i ← lenght(A)/2 downto 1 do MAX-HEAPIFY(A,i)
► Dato un Array qualsiasi vogliamo ordinarlo con l’HEAP-SORT HEAPSORT(A) BUILD-MAXHEAP(A) for i ← lenght(A) downto 2 do “scambia A[1] con A[i]” A[0] ← A[0] - 1 MAX-HEAPIFY(A,1)
#include <stdio.h> #define N 100 // PARENT(i), LEFT(i), RIGHT(i) e scambia int PARENT(int i) { return (i/2); } int LEFT(int i) { return 2*i; } int RIGHT(int i){ return (2*i)+1; } void scambia(int HEAP[], int ind1, int ind2){ int appo; appo = HEAP[ind1]; HEAP[ind1]=HEAP[ind2]; HEAP[ind2]=appo; }
void MAXHEAPIFY(int HEAP[], int i){ int largest; int l = LEFT(i); int r = RIGHT(i); if ((l <= HEAP[0]) && (HEAP[l] > HEAP[i])) largest = l; else largest = i; if ((r <= HEAP[0]) && (HEAP[r] > HEAP[largest])) largest = r; if (largest != i) { scambia(HEAP,i,largest); MAXHEAPIFY(HEAP,largest); } }
void BUILD_MAXHEAP(int HEAP){ int i; HEAP[0] = HEAP[N-1]; for (i=(HEAP[N-1]/2);i>0;i--) MAXHEAPIFY(HEAP,i); }
void HEAP_SORT(int HEAP[]) { int i; BUILD_MAXHEAP(HEAP); for(i=HEAP[N-1];i>1;i--) { scambia(HEAP,1,i); (HEAP[0])--; MAXHEAPIFY(HEAP,1); } }
Corso di Algoritmi e Strutture Dati APPUNTI SUL LINGUAGGIO C Esercizi di base FINE