1
Fork 0
mirror of https://github.com/Steffo99/appunti-magistrali.git synced 2024-11-22 10:44:17 +00:00
appunti-steffo/2 - Algoritmi e strutture dati/11 - Merge Sort.md

102 lines
2.5 KiB
Markdown
Raw Normal View History

# Merge sort
Il _merge sort_ è una soluzione **ricorsiva** all'ordinamento per confronto.
## Funzionamento
Per questo algoritmo, utilizziamo la tecnica del **divide et impera**.
1. _Divide_: Divido A in **due parti**.
2. _Impera_: Metto **separatamente in ordine** le parti.
3. _Unisci_: **Unisco** le due parti.
Consideriamo come **caso base** della ricorsione una parte composta da un numero, che ovviamente è già ordinata con sè stessa.
### Merge
Per **unire le due parti** usiamo una funzione detta `merge()`.
Costruiamo una nuova sequenza uguale alla sequenza 1, ma **aggiungiamo alla fine un valore sentinella** sempre maggiore di tutti gli elementi contenuti.
> ```
> | 1 | 3 | 7 | 8 | ∞ |
> ```
Facciamo **la stessa cosa** per la sequenza due.
> ```
> | 2 | 4 | 5 | 6 | ∞ |
> ```
Prendo i primi numeri delle due sequenze e **metto il più piccolo nella sequenza iniziale**.
> ```
> | 1 | 2 | 3 | | | | | |
> | | | 7 | 8 | ∞ |
> | | 4 | 5 | 6 | ∞ |
> ```
**Continuo** finchè non ho messo tutti i numeri; **grazie alla sentinella non usciremo mai dalla sequenza**, in quanto essa è sempre maggiore di tutti gli altri numeri.
> ```
> | 1 | 2 | 3 | 4 | 5 | 6 | | |
> | | | 7 | 8 | ∞ |
> | | | | | ∞ |
> ```
Quando **rimangono solo le sentinelle** significa che abbiamo aggiunto tutti gli elementi, e quindi abbiamo finito.
> ```
> | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
> | | | | | ∞ |
> | | | | | ∞ |
> ```
## Costo computazionale
| Categoria | Upper bound | Lower bound | Tight bound |
|-----------|-------------|-------------|-------------|
| Tempo | `O(n log n)` | `Ω(n log n)` | **`θ(n log n)`** |
Il merge sort è un algoritmo ricorsivo con un **caso base in tempo costante** e che **richiama sè stesso 2 volte**.
```latex
T(n) =\\
\\
Θ(1) \qquad n=1\\
2 T(\frac{n}{2}) + Θ(n) \qquad n \neq 1
```
Applicando il **caso particolare del Master Theorem**, otteniamo:
```latex
T(n) =\\
\\
Θ(1) \qquad n=1\\
Θ(n log n) \qquad n \neq 1
```
## Pseudocodice
```python
def merge_sorted(part):
# Caso base
if len(part) == 1:
return part
# Divide
middle = len(part) // 2
part_a = part[:middle]
part_b = part[middle:]
# Impera
sort_a = merge_sorted(part_a)
sort_b = merge_sorted(part_b)
# Combina
return merge(sort_a, sort_b)
```
## Visualizzazione
[hackerearth.com](https://www.hackerearth.com/practice/algorithms/sorting/merge-sort/visualize/)
[visualgo.net](https://visualgo.net/bn/sorting) (Nota: visualizza solo la fase _Unisci_ del sort)