universityin-classsubject-2101
2023-10-19
Algoritmi
Counting & Radix Sort
Per ordinare un array sulla base di più chiavi è sufficiente ordinare per ogni chiave dalla meno importante alla più importante. È necessario che gli algoritmi di ordinamento utilizzati siano stabili, altrimenti il metodo non funziona.
L’ordinamento, anche se non è stabile, se utilizzato solo sulla prima iterazione, rende comunque l’algoritmo funzionante, ma non stabile.
Per ordinare numeri grossi con il counting sort si può utilizzare il metodo precedente, ordinando per ogni cifra separatamente.
Si può utilizzare n%10
per ottenere l’ultima cifra e utilizzare i
-esima cifra da destra.
Questo algoritmo è detto Radix Sort.
/*
se A=[8532, 2553, 2634] e i=2 il counting sort vede [5, 5, 6]
*/
void radixSort(int* A, int n) {
int c = getMaxNumberOfDigits(A, n); // se max(A)=1'000'000 => c=7
for (int i = 0; i < c; i++) {
countingSort(A, n, i); // dove i è la posizione (da destra) della cifra su cui ordinare
}
}
Dizionario
È importante avere una ricerca veloce, a costo di sacrificare tempi di inserimento e cancellazione.
Tabella a indirizzamento diretto
Si utilizza una tabella a indici da
void insert(int* A, int x) {
A[x] = x;
}
void remove(int* A, int x) {
A[x] = NULL; // pseudocodice
}
bool search(int* A, int x) {
return A[x] != NULL;
}
Si può ottimizzare sostituendo il tipo dell’array da int
in bool
(mettendo 1
se l’elemento è presente, altrimenti 0
).
Nota
Questa implementazione non funziona quando bisogna conservare numeri molto grandi (servirebbe un array di uguale dimensione).
Tabella Hash
Si consideri
Si utilizza una tabella (chiamata
La tabella contiene meno celle delle chiavi da rappresentare:
Si utilizza un oracolo: è una funzione, detta funzione hash, che prende in input un elemento di
È importante che la funzione hash ritorni sempre lo stesso valore per lo stesso numero dato in input.
Essendo
Esistono molti metodi per risolvere il problema e conservare
Metodo concatenazione
Si utilizzano le liste.
Ogni elemento di
Con questo metodo bisogna effettuare la ricerca all’interno di una lista in tempo lineare (e non più costante).
Consideriamo
Ogni operazione di ricerca impiega in media
void insert(list* T, int k) {
T[h(k)].insert(k);
}
void remove(list* T, int k) {
T[h(k)].remove(k);
}
bool search(list* T, int k) {
return T[h(k)].search(k);
}
Metodo indirizzamento aperto
prossima lezione
Proprietà della Hash Function
L’hashing uniforme semplice è una proprietà che indica la probabilità che la funzione di hash distribuisca in modo uguale gli elementi nelle celle.
Implementazione
Ci sono vari metodi per implementare la funzione hash.
Metodo divisione
Se consideriamo
Metodo moltiplicazione
Si consideri
Si prende
A differenza del caso precedente, la scelta di
Considerando