Quando inserisci un elemento nel mezzo dell'array ordinato, devi prima trovare la posizione corretta (ad es. tramite ricerca binaria), e devi spostare tutti gli elementi a destra della posizione di inserimento di un posto a destra per fare spazio.
- Confronti: O (log n) per inserimento, O (n log n) per tutti gli elementi
- Movimenti: O (n) per inserimento, O (n²) per tutti gli elementi
Quando inserisci un elemento alla fine e quindi utilizzi un passaggio di ordinamento per inserimento, non è necessario conoscere la posizione di inserimento in primo piano. Tuttavia, il passaggio di ordinamento per l'inserimento confronta tutti gli elementi più grandi e sposta tutti gli elementi più grandi di un passo verso destra.
- Confronti: O (n) per inserimento, O (n²) per tutti gli elementi
- Movimenti: O (n) per inserimento, O (n²) per tutti gli elementi
Pseudocodice di inserimento:
elements.add(newElement); // at the end
// Move the new element forward in the array
// until it is at the correct position.
// This loop has O(n) average time complexity.
//
// Example ordering for ints:
// boolean isOrdered(int a, int b) {
// return a <= b;
// }
int i = elements.size() - 1;
while (i > 0 && !isOrdered(elements[i - 1], elements[i])) {
swap(elements, i - 1, i);
i--;
}
Questo significa che usare l'ordinamento di inserimento invece di inserire l'elemento in una posizione trovata tramite la ricerca binaria comporta lo stesso numero di movimenti, ma richiede paragoni molto più. Quindi inserire il nuovo elemento direttamente nella posizione ordinata è più efficiente se i confronti necessari sono costosi, ma entrambi gli algoritmi sono essenzialmente O (n²) (cioè quadratico) nel corso di tutti gli inserimenti.
Se vuoi essere più efficiente, devi pensare a come stai usando i dati.
-
Se non hai bisogno che gli elementi siano sempre ordinati: prima inserisci gli tutti elementi, quindi ordinali con un algoritmo di ordinamento O (n log n).
-
Se è necessario accedere agli elementi ordinati prima che tutti gli elementi siano disponibili:
- Se hai solo bisogno di accedere all'elemento massimo o minimo, usa un Heap.
- Se hai bisogno di accedere a tutti gli articoli correnti nel loro ordine, usa un albero di ricerca binaria auto-bilanciato, ad es. come implementato in TreeMap di Java.
L'inserimento di elementi in un ArrayList potrebbe ancora essere l'opzione corretta, ad es. se il numero di elementi è molto piccolo.