Tengo una matriz de JavaScript ordenada y deseo insertar un elemento más en la matriz, de modo que la matriz resultante permanezca ordenada. Ciertamente podría implementar una simple función de inserción de estilo de clasificación rápida:
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));
[ADVERTENCIA] este código tiene un error al intentar insertarlo al comienzo de la matriz, por ejemplo insert(2, [3, 7 ,9]
) produce incorrectos [3, 2, 7, 9].
Sin embargo, noté que las implementaciones de la función Array.sort podrían hacer esto por mí y de forma nativa:
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));
¿Hay una buena razón para elegir la primera implementación sobre la segunda?
Editar : Tenga en cuenta que para el caso general, una inserción de O (log (n)) (como se implementó en el primer ejemplo) será más rápida que un algoritmo de clasificación genérico; sin embargo, este no es necesariamente el caso de JavaScript en particular. Tenga en cuenta que:
- El mejor caso para varios algoritmos de inserción es O (n), que sigue siendo significativamente diferente de O (log (n)), pero no tan malo como O (n log (n)) como se menciona a continuación. Se reduciría al algoritmo de clasificación particular utilizado (ver implementación de Javascript Array.sort? )
- El método de clasificación en JavaScript es una función nativa, por lo que puede obtener enormes beneficios: O (log (n)) con un coeficiente enorme puede ser mucho peor que O (n) para conjuntos de datos de tamaño razonable.
splice()
(por ejemplo, su primer ejemplo) ya es O (n). Incluso si no crea internamente una nueva copia de toda la matriz, potencialmente tiene que desviar todos los n elementos hacia atrás 1 posición si el elemento se va a insertar en la posición 0. Tal vez sea rápido porque es una función nativa y la constante es bajo, pero es O (n) de todos modos.
parseInt
uso Math.floor
en su lugar. Math.floor
es mucho más rápido que parseInt
: jsperf.com/test-parseint-and-math-floor