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).