Insertion sort: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Pagina sostituita con '...'
Etichette: Rimozione delle Categorie da parte di nuovo utente o IP Modifica visuale: commutato
m Annullate le modifiche di 5.96.68.146 (discussione), riportata alla versione precedente di PadronFrodo
Riga 1:
{{Algoritmo
...
|class=[[Algoritmo di ordinamento]]
|image=[[Image:Insertion sort animation.gif|none|Esempio di ordinamento di una lista di numeri casuali.]]
|caption=Esempio di ordinamento di una lista di numeri casuali.
|data=[[Array]]
|time=O(''n''<sup>2</sup>)
|best-time=O(''n'')
|average-time=O(''n''<sup>2</sup>)
|space=O(''n'') totale<br />O(''1'') ausiliaria
|optimal=Sì (nel caso di inserimento di alcuni valori in una lista quasi ordinata)
}}
L''''Insertion sort''', in italiano '''ordinamento a inserimento''', è un [[algoritmo]] relativamente semplice per [[Algoritmo di ordinamento|ordinare]] un [[array]]. Non è molto diverso dal modo in cui un essere umano, spesso, ordina un mazzo di carte. Esso è un [[Algoritmo in loco|algoritmo ''in place'']], cioè ordina l'array senza doverne creare una copia, risparmiando memoria. Pur essendo molto meno efficiente di algoritmi più avanzati, può avere alcuni vantaggi: ad esempio, è semplice da implementare ed è efficiente per insiemi di partenza che sono quasi ordinati.
 
== Descrizione dell'algoritmo ==
L'algoritmo solitamente ordina la sequenza sul posto. Si assume che la sequenza da ordinare sia partizionata in una sottosequenza già ordinata, all'inizio composta da un solo elemento, e una ancora da ordinare. Alla <math>k</math>-esima iterazione, la sequenza già ordinata contiene <math>k</math> elementi. In ogni iterazione, viene rimosso un elemento dalla sottosequenza non ordinata (scelto, in generale, arbitrariamente) e ''inserito'' (da cui il nome dell'algoritmo) nella posizione corretta della sottosequenza ordinata, estendendola così di un elemento.
 
[[File:AnimazioneInsertionSort.gif|left|thumb|upright=2.2|Simulazione dell'insertion sort su di un array]]
 
Per fare questo, un'implementazione tipica dell'algoritmo utilizza due indici: uno punta all'elemento da ordinare e l'altro all'elemento immediatamente precedente. Se l'elemento puntato dal secondo indice è maggiore di quello a cui punta il primo indice, i due elementi vengono scambiati di posto; altrimenti il primo indice avanza. Il procedimento è ripetuto finché si trova nel punto in cui il valore del primo indice deve essere inserito.
Il primo indice punta inizialmente al secondo elemento dell'array, il secondo inizia dal primo. L'algoritmo così tende a spostare man mano gli elementi maggiori verso destra.
 
==Pseudocodice==
Segue lo [[pseudocodice]] per l'algoritmo (si assume che la numerazione degli elementi negli array inizi da 0).
 
'''function''' insertionSort(array A)
'''for''' i ← 1 '''to''' length[A] '''do'''
value ← A[i]
j ← i-1
'''while''' j >= 0 '''and''' A[j] > value '''do'''
A[j + 1] ← A[j]
j ← j-1
A[j+1] ← value
 
Segue lo [[pseudocodice]] per [[Programmazione funzionale|linguaggi funzionali]].
 
insert :: Ord a => a -> [a] -> [a]
insert item [] = [item]
insert item (h:t) | item <= h = item:h:t
| otherwise = h:(insert item t)
insertsort :: Ord a => [a] -> [a]
insertsort [] = []
insertsort (h:t) = insert h (insertsort t)
 
<!-- NON INSERITE IMPLEMENTAZIONI QUI, METTETELE SU WIKIBOOKS, TROVATE IL LINK IN "ALTRI PROGETTI" -->
=== Esempio di funzionamento ===
 
Di seguito sono mostrati i passi compiuti dall'algoritmo per ordinare la sequenza [3, 7, 4, 9, 5, 2, 6, 1]. In ogni passo, l'elemento sottolineato è quello considerato, mentre quello in grassetto è l'elemento spostato nel passo precedente.
 
<u>3</u> 7 4 9 5 2 6 1
 
'''3''' <u>7</u> 4 9 5 2 6 1
 
3 '''7''' <u>4</u> 9 5 2 6 1
 
3 '''4''' 7 <u>9</u> 5 2 6 1
 
3 4 7 '''9''' <u>5</u> 2 6 1
 
3 4 '''5''' 7 9 <u>2</u> 6 1
 
'''2''' 3 4 5 7 9 <u>6</u> 1
 
2 3 4 5 '''6''' 7 9 <u>1</u>
 
'''1''' 2 3 4 5 6 7 9
 
== Analisi ==
Il caso ottimo per l'algoritmo è quello in cui la sequenza di partenza sia già ordinata. In questo caso, l'algoritmo ha tempo di esecuzione lineare, ossia <math>\Theta(n)</math>. Infatti, in questo caso, in ogni iterazione il primo elemento della sottosequenza non ordinata viene confrontato solo con l'ultimo della sottosequenza ordinata.
Il caso pessimo è invece quello in cui la sequenza di partenza sia ordinata al contrario. In questo caso, ogni iterazione dovrà scorrere e spostare ogni elemento della sottosequenza ordinata prima di poter inserire il primo elemento della sottosequenza non ordinata. Pertanto, in questo caso l'algoritmo di insertion sort ha complessità temporale quadratica, ossia <math>\Theta(n^2)</math>.
Anche il caso medio ha complessità quadratica, il che lo rende impraticabile per ordinare sequenze grandi.
Pur avendo complessità elevata, tuttavia, risulta essere l'algoritmo di ordinamento più veloce per array piccoli. Un algoritmo simile all'Insertion Sort ma dalla complessità minore è lo [[Shell sort]]. Anche lo shell sort non è in grado di competere con la combinazione dell'insertion sort con un algoritmo di tipo ''[[divide et impera (informatica)|divide et impera]]'', quale il [[quick sort]] o il [[merge sort]], ossia all'uso dell'algoritmo ''divide et impera'' per ridurre il problema all'ordinamento di sequenze di dimensione inferiore a una certa soglia, che verranno trattate con l'insertion sort.
 
== Bibliografia ==
* {{cita libro| Thomas | Cormen | Introduction to Algorithms | 1998 | The MIT Press | Cambridge, Massachusetts | coautori=Charles E. Leiserson, [[Ronald Rivest]]| capitolo=Introduction | ed=2 }}
 
== Altri progetti ==
{{Interprogetto|commons=Category:Insertion sort|b=Implementazioni di algoritmi/Insertion sort|b_oggetto=implementazioni|b_preposizione=di}}
 
{{ordinamento}}
 
[[Categoria:Algoritmi di ordinamento]]