Eu tenho uma matriz JavaScript classificada e quero inserir mais um item na matriz, para que a matriz resultante permaneça classificada. Eu certamente poderia implementar uma função simples de inserção no estilo 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));
[AVISO] este código tem um erro ao tentar inserir no início da matriz, por exemplo insert(2, [3, 7 ,9]
) produz incorreto [3, 2, 7, 9].
No entanto, notei que as implementações da função Array.sort podem fazer isso por mim 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));
Existe um bom motivo para escolher a primeira implementação sobre a segunda?
Editar : observe que, no caso geral, uma inserção de O (log (n)) (conforme implementada no primeiro exemplo) será mais rápida que um algoritmo de classificação genérico; no entanto, esse não é necessariamente o caso do JavaScript em particular. Observe que:
- O melhor caso para vários algoritmos de inserção é O (n), que ainda é significativamente diferente de O (log (n)), mas não tão ruim quanto O (n log (n)), conforme mencionado abaixo. Seria o algoritmo de classificação específico usado (consulte Implementação Javascript Array.sort? )
- O método de classificação no JavaScript é uma função nativa; portanto, é possível obter enormes benefícios - O (log (n)) com um coeficiente enorme ainda pode ser muito pior que O (n) para conjuntos de dados de tamanho razoável.
splice()
(por exemplo, seu 1º exemplo) já é O (n). Mesmo que não crie internamente uma nova cópia de toda a matriz, ele potencialmente precisará desviar todos os n itens para trás 1 posição para que o elemento seja inserido na posição 0. Talvez seja rápido porque é uma função nativa e a constante é baixo, mas é O (n) no entanto.
parseInt
use em seu Math.floor
lugar. Math.floor
é muito mais rápido que parseInt
: jsperf.com/test-parseint-and-math-floor