Ho un array JavaScript ordinato e desidero inserire un altro elemento nell'array in modo che l'array risultante rimanga ordinato. Potrei certamente implementare una semplice funzione di inserimento in stile quicksort:
var array = [1,2,3,4,5,6,7,8,9];
var element = 3.5;
function insert(element, array) {
array.splice(locationOf(element, array) + 1, 0, element);
return array;
}
function locationOf(element, array, start, end) {
start = start || 0;
end = end || array.length;
var pivot = parseInt(start + (end - start) / 2, 10);
if (end-start <= 1 || array[pivot] === element) return pivot;
if (array[pivot] < element) {
return locationOf(element, array, pivot, end);
} else {
return locationOf(element, array, start, pivot);
}
}
console.log(insert(element, array));
[ATTENZIONE] questo codice ha un bug quando si tenta di inserire all'inizio dell'array, ad esempio insert(2, [3, 7 ,9]
) produce errato [3, 2, 7, 9].
Tuttavia, ho notato che le implementazioni della funzione Array.sort potrebbero potenzialmente farlo per me e nativamente:
var array = [1,2,3,4,5,6,7,8,9];
var element = 3.5;
function insert(element, array) {
array.push(element);
array.sort(function(a, b) {
return a - b;
});
return array;
}
console.log(insert(element, array));
C'è una buona ragione per scegliere la prima implementazione rispetto alla seconda?
Modifica : si noti che per il caso generale, un inserimento O (log (n)) (come implementato nel primo esempio) sarà più veloce di un algoritmo di ordinamento generico; tuttavia questo non è necessariamente il caso di JavaScript in particolare. Nota che:
- Il caso migliore per diversi algoritmi di inserimento è O (n), che è ancora significativamente diverso da O (log (n)), ma non è così male come O (n log (n)) come menzionato di seguito. Dipenderebbe dal particolare algoritmo di ordinamento utilizzato (vedi l' implementazione di Javascript Array.sort? )
- Il metodo di ordinamento in JavaScript è una funzione nativa, quindi potenzialmente realizza enormi vantaggi - O (log (n)) con un coefficiente enorme può ancora essere molto peggio di O (n) per insiemi di dati di dimensioni ragionevoli.
splice()
(ad esempio il tuo primo esempio) è già O (n). Anche se non crea internamente una nuova copia dell'intero array, potenzialmente deve spostare tutti gli n elementi indietro di 1 posizione se l'elemento deve essere inserito in posizione 0. Forse è veloce perché è una funzione nativa e la costante è basso, ma è comunque O (n).
parseInt
usare Math.floor
invece invece. Math.floor
è molto più veloce di parseInt
: jsperf.com/test-parseint-and-math-floor