Il problema dell’ordinamento di una sequenza di valori (e.g., numeri) può essere così formulato:
L’algoritmo seguente risolve il problema:
InsertionSort(array A)
1 for j = 2 to Lenght(A) do
2 Key = A[j] /* Scelta del j-esimo elemento da ordinare */
3 i = j-1 /* [1...i] è la porzione ordinata */
4 while (i>0 && A[i]>Key) do
5 A[i+1] = A[i]
6 i=i-1
7 A[i-1] = Key
Procediamo con l’analisi del tempo di esecuzione:
InsertionSort(array A)
1 for j = 2 to Lenght(A) do
2 Key = A[j]
3 i = j-1
4 while (i>0 && A[i]>Key) do
5 A[i+1] = A[i]
6 i=i-1
7 A[i-1] = Key
Possiamo ora completare l’analisi del tempo di esecuzione:
InsertionSort(array A)
1 for j = 2 to Lenght(A) do
2 Key = A[j]
3 i = j-1
4 while (i>0 && A[i]>Key) do
5 A[i+1] = A[i]
6 i=i-1
7 A[i-1] = Key
Da cui otteniamo:
Poiché la definizione di T(n) non dipende solo da n, ma anche dai parametri , non è possibile calcolarla direttamente.
L’algoritmo, infatti, può avere un tempo di esecuzione molto diverso anche per sequenze diverse della stessa lunghezza.
Per procedere ad un’analisi asintotica, analizzeremo il tempo di esecuzione in tre casi paradigmatici:
La funzione del tempo di esecuzione nel caso migliore, , fornisce una stima del limite inferiore asintotico per il tempo di esecuzione dell’algoritmo;
La funzione del tempo di esecuzione nel caso peggiore, , fornisce una stima del limite superiore asintotico per il tempo di esecuzione dell’algoritmo;
La funzione del tempo di esecuzione nel caso medio, , fornisce una stima asintotica per il tempo di esecuzione dell’algoritmo nella maggior parte dei casi;
Quando possiamo affermare che . Non è quindi necessario effettuare l’analisi di caso medio.
Il caso migliore si ha quando l’array è già ordinato.
Infatti, in questo caso, per ogni valore di j, non viene mai eseguito il corpo del while ().
Segue che, per ogni valore di j, e .
L’espressione per T(n) si riduce quindi alla seguente:
Nel caso migliore, quindi, InsertionSort impiega tempo lineare sulla dimensione della sequenza.
Il caso peggiore si ha quando l’array è ordinato in ordine inverso
Infatti, in questo caso, per ogni valore di j, il corpo del while viene eseguito fino a che i=0 (, per ogni 0<i<j)
Segue che, per ogni valore di j, e .
L’espressione per T(n) si riduce quindi alla seguente:
Nel caso peggiore, quindi, InsertionSort impiega tempo quadratico sulla dimensione della sequenza.
In base alle considerazioni precedenti, possiamo, quindi, ragionare come segue:
In colclusione, dall’analisi effettuata possiamo concludere che il tempo di esecuzione di InsertionSort è asintoticamente quadratico.
Infatti, sia nel Caso Peggiore che nel Caso Medio, esso segue lo stesso andamento delle funzioni quadratiche della forma
Solo nel Caso Migliore il tempo di esecuzione segue l’andamento delle funzioni lineari del tipo
Rappresentazione grafica delle funzioni di tempo di InsertionSort nei tre casi analizzati (migliore, peggiore, medio).