Algoritmi e Strutture Dati I – La Spezia
Algoritmi di ordinamento, divide-and-conquer e loro uso:
1. Quali fra gli algoritmi di ordinamento visti a lezione è stabile ?
Quale trasformazione dell’input permetterebbe di rendere tutti gli
algoritmi stabili ? Come la realizzereste nell’algoritmo ?
2. Cosa accade all’algoritmo PERNO(A,p,r) visto in classe se A[p]
risulta minore di tutti gli elementi in A[p+1..r] ?
3. Cosa accade all’algoritmo PERNO(A,p,r) visto in classe se A[p]
risulta maggiore di tutti gli elementi in A[p+1..r] ?
4. Cosa accade nell’algoritmo PERNO(A,p,r) visto in classe agli
elementi uguali a A[p]?
5. Cosa accade nell’algoritmo PERNO(A,p,r) visto in classe se gli
elementi in A[p..r] sono tutti uguali?
6. Proporre un algoritmo Perno(A,p,r) che riorganizza A[p..r] come
segue: colloca prima tutti gli elementi minori di A[p], poi quelli
uguali a A[p], e infine quelli maggiori di A[p].
7. Ricordare che il MERGE-SORT ha complessità (n log n), mentre
se i numeri da ordinare sono degli interi minori di k, allora il
RADIX-SORT ha complessità O(n log k / log n).
a. Se k = (2n), qual’è la complessità del RADIX-SORT se
espressa in funzione solo di n ? Quali dei due algoritmi è il
più veloce ?
b. Se x = (log n)2 e k = (2x), qual’è la complessità del
RADIX-SORT ? Quali dei due algoritmi è il più veloce ?
c. Se k = (n5), qual’è la complessità del RADIX-SORT se
espressa in funzione solo di n ? Quali dei due algoritmi è il
più veloce ?
8. Scrivere un algoritmo di complessità O(n log n) che, data un
insieme S di n reali e un’altro reale x, stabilisce se in S esistono due
elementi la cui somma è proprio x.
9. Siano dati due array A[1..n] e B[1..n] ordinati in modo crescente.
Progettare un algoritmo che trova il mediano di entrambi. Lo si può
fare in O(log n) ?
10.Sia dato un array di numeri A[1..n], con n multiplo di 6 (per
semplicità).
a. Scrivere un algoritmo che trova in A un numero x tale che:
(i) x cade nei 2/3 centrali dell’array (x=A[i] e n/6 < i < 5n/6),
(ii) x cade nei 2/3 centrali di A anche dopo che questo è stato
ordinato.
b. Dimostrare che l’elemento x esiste sempre.
c. Scrivere un algoritmo che trova x in tempo O(n).
11. Siano u e v due numeri di n bit ciascuno, dove n per semplicità è
una potenza del 2.
a. Dimostrare che l’algoritmo tradizionale di moltiplicazione
richiede complessità O(n2).
b. Progettare un algoritmo basato su divide-and-conquer che
divide i numeri in due parti di lunghezza uguale, e calcola
uv = (a 2n/2 + b) (c 2n/2 + d) = a c 2n + (ad+bc) 2n/2 + bd, dove
le moltiplicazioni ac, ad, bc, bd sono ottenute
ricorsivamente.
c. Calcolare la complessità asintotica di questo nuovo
algoritmo.
d. Cosa accade se (ad+bc) è calcolato come (a+b) (c+d) –ac-bd.
12. Estendere l’algoritmo del punto precedente alla moltiplicazione di
due matrici quadrate n  n.
Heap e Heapsort:
13.Per un heap di n nodi, costruire un esempio su cui HEAPIFY costa
( log n).
14. Dimostrare che ci sono al massimo n / 2h+1 nodi di altezza h in
un heap di dimensione n.
15.Qual’è la complessità dell’heapsort quando l’array è già in ordine
decrescente ? E se fosse già in ordine crescente ?
16.Progettare un algoritmo che esegue l’operazione di DELETE da
uno heap.
17.Progettare un algoritmo che esegue l’operazione di CHANGE(x,)
aggiungendo  al valore contenuto nel nodo x dello heap,
ristrutturandolo propriamente. Cosa accade se  è negativo ?
Algoritmi di ordinamento lineare:
18. Dimostrare per induzione la correttezza di RADIX-SORT.
19. Progettare un algoritmo che ordina n interi in [1..n2] in tempo
O(n).