Ciao, oggi vedremo assieme una spiegazione approfondita e chiara del Merge Sort, accompagnata alla fine da un video esplicativo — incluso uno con un “balletto” animato che segue i passi dell’algoritmo.
Il merge sort è un algoritmo di ordinamento efficiente che utilizza un approccio “divide et impera“. Divide ricorsivamente l’array da ordinare in sottoarray più piccoli, ordina questi sottoarray e infine combina (fonde) i risultati ordinati per ottenere l’array completamente ordinato. La sua complessità temporale è O(n log n), rendendolo ideale per ordinare grandi quantità di dati.
Il merge sort è stato ideato da John von Neumann negli anni ’40. Tuttavia, il concetto di merge sort è stato formalizzato e pubblicato per la prima volta da John von Neumann e da un collega, Herman Goldstine, nel 1945 nel documento intitolato “Planning and Coding of Problems for an Electronic Computing Instrument”.
Questo algoritmo di ordinamento è noto per la sua efficienza e per il suo approccio divide et impera, che lo rende una delle scelte popolari per l’ordinamento di grandi quantità di dati.
In sintesi
Merge Sort: algoritmo robusto, stabile, efficiente e prevedibile.
Strategia: dividere‑ordinare‑unire.
Complessità: sempre O(n log n), con spazio extra.
Ottimo per scenari dove la stabilità conta o i dati sono molto grandi o su disco.
Merge Sort: Dividi per conquistare (cioè?)
1. Idea chiave
Merge Sort è un algoritmo ricorsivo che utilizza la strategia divide et impera:
Se la lista ha 0 o 1 elemento, è già ordinata.
Altrimenti, dividi la lista in due metà.
Ordina ciascuna metà in modo ricorsivo.
Unisci (merge) le due metà ordinate in una lista unica, mantenendo l’ordine.
È stabile (rispetta l’ordine relativo di elementi uguali), e garantisce complessità O(n log n) nel caso medio e peggiore, con spazio ausiliario O(n).
function merge_sort(A):
if len(A) ≤ 1:
return A
mid = len(A)//2
left = merge_sort(A[:mid])
right = merge_sort(A[mid:])
return merge(left, right)
function merge(L, R):
result = []
while L and R:
if L[0] ≤ R[0]:
result.append(L.pop(0))
else:
result.append(R.pop(0))
result += L + R
return result
Complessità:
Tempo: T(n) = 2 T(n/2) + Θ(n) → Θ(n log n)
Spazio: O(n) (lo spazio per le fusioni)
4. Quando usarlo?
Stabile: mantiene l’ordine degli elementi duplicati.
Prevedibile: nessun caro caso peggiore, sempre O(n log n).
Ideale per:
strutture a accesso sequenziale (es. liste collegate)
Implementazione in Python dell’algoritmo merge sort
# Python program for implementation of MergeSort
def mergeSort(arr):
if len(arr) > 1:
# Finding the mid of the array
mid = len(arr)//2
# Dividing the array elements
L = arr[:mid]
# Into 2 halves
R = arr[mid:]
# Sorting the first half
mergeSort(L)
# Sorting the second half
mergeSort(R)
i = j = k = 0
# Copy data to temp arrays L[] and R[]
while i < len(L) and j < len(R):
if L[i] <= R[j]:
arr[k] = L[i]
i += 1
else:
arr[k] = R[j]
j += 1
k += 1
# Checking if any element was left
while i < len(L):
arr[k] = L[i]
i += 1
k += 1
while j < len(R):
arr[k] = R[j]
j += 1
k += 1
# Code to print the list
def printList(arr):
for i in range(len(arr)):
print(arr[i], end=" ")
print()
# Driver Code
if __name__ == '__main__':
arr = [12, 11, 13, 5, 6, 7]
print("Given array is")
printList(arr)
mergeSort(arr)
print("\nSorted array is ")
printList(arr)
# This code is contributed by Mayank Khanna
# source: https://www.geeksforgeeks.org/merge-sort/
(fonte)
Analisi della complessità del merge sort
La complessità temporale del merge sort è generalmente calcolata come O(n log n), dove ‘n’ è il numero di elementi nell’array da ordinare. Questo rappresenta la complessità nel caso peggiore, medio e migliore.
Nel merge sort, il processo di divisione ricorsiva dell’array in sottoarray di dimensioni sempre più piccole richiede un tempo logaritmico, O(log n), perché l’array viene diviso a metà ripetutamente fino a quando non si ottengono singoli elementi o sottoproblemi di dimensione 1.
Successivamente, il processo di fusione dei singoli elementi o sottoparti ordinate richiede un tempo lineare, O(n), dove ‘n’ è il numero totale di elementi nell’array. La fusione di due sottoparti ordinate richiede di scorrere attraverso entrambe le sottoparti, e in un contesto di fusione ricorsiva, questa operazione viene eseguita proporzionalmente al numero totale di elementi da unire.
Quindi, poiché l’intero array viene diviso in log(n) livelli e ciascun livello richiede un tempo lineare O(n) per la fusione, la complessità totale del merge sort è O(n log n).
Questo rende il merge sort un algoritmo molto efficiente per ordinare grandi quantità di dati, mantenendo una buona performance anche per dimensioni elevate di array da ordinare.
Esempi pratici di funzionamento del merge sort
Ecco una semplice spiegazione dell’algoritmo, passaggio dopo passaggio.
Per comprendere il flusso di utenti e poter garantire una migliore esperienza d'uso utilizziamo un unico cookie per l'analisi del traffico web. Ci teniamo alla tua privacy e non raccogliamo nulla che non ci interessa e non cediamo nessun dato. Per saperne di più leggi la nostra Privacy Policy.
Funzionale
Sempre attivo
L'archiviazione tecnica o l'accesso sono strettamente necessari al fine legittimo di consentire l'uso di un servizio specifico esplicitamente richiesto dall'abbonato o dall'utente, o al solo scopo di effettuare la trasmissione di una comunicazione su una rete di comunicazione elettronica.
Preferenze
L'archiviazione tecnica o l'accesso sono necessari per lo scopo legittimo di memorizzare le preferenze che non sono richieste dall'abbonato o dall'utente.
Statistiche
Cookie necessario al corretto funzionamento di Matomo Analytics per l'anali del traffico web.L'archiviazione tecnica o l'accesso che viene utilizzato esclusivamente per scopi statistici anonimi. Senza un mandato di comparizione, una conformità volontaria da parte del vostro Fornitore di Servizi Internet, o ulteriori registrazioni da parte di terzi, le informazioni memorizzate o recuperate per questo scopo da sole non possono di solito essere utilizzate per l'identificazione.
Marketing
L'archiviazione tecnica o l'accesso sono necessari per creare profili di utenti per inviare pubblicità, o per tracciare l'utente su un sito web o su diversi siti web per scopi di marketing simili.