Mam posortowaną tablicę JavaScript i chcę wstawić jeszcze jeden element do tablicy, tak aby wynikowa tablica pozostała posortowana. Z pewnością mógłbym zaimplementować prostą funkcję wstawiania w stylu 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));
[OSTRZEŻENIE] ten kod ma błąd, gdy próba wstawienia na początek tablicy, np. insert(2, [3, 7 ,9]
) Daje niepoprawne [3, 2, 7, 9].
Jednak zauważyłem, że implementacje funkcji Array.sort mogą potencjalnie zrobić to dla mnie i natywnie:
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));
Czy jest dobry powód, aby wybrać pierwszą implementację zamiast drugiej?
Edycja : Zauważ, że w ogólnym przypadku wstawienie O (log (n)) (jak zaimplementowano w pierwszym przykładzie) będzie szybsze niż ogólny algorytm sortowania; jednakże niekoniecznie ma to miejsce w szczególności w przypadku JavaScript. Zauważ, że:
- Najlepszym przypadkiem dla kilku algorytmów wstawiania jest O (n), które nadal znacznie różni się od O (log (n)), ale nie tak źle jak O (n log (n)), jak wspomniano poniżej. Sprowadziłoby się to do konkretnego użytego algorytmu sortowania (patrz implementacja Javascript Array.sort? )
- Metoda sortowania w JavaScript jest funkcją natywną, więc potencjalnie przynosząca ogromne korzyści - O (log (n)) z ogromnym współczynnikiem może nadal być znacznie gorsza niż O (n) dla zbiorów danych o rozsądnych rozmiarach.
splice()
(np. Twój pierwszy przykład), jest już O (n). Nawet jeśli wewnętrznie nie tworzy nowej kopii całej tablicy, potencjalnie musi przesuwać wszystkie n elementów wstecz o 1 pozycję, jeśli element ma być wstawiony na pozycji 0. Może to szybko, ponieważ jest to funkcja natywna, a stała to niski, ale mimo to jest O (n).
parseInt
używaj Math.floor
zamiast tego użyj . Math.floor
jest znacznie szybszy niż parseInt
: jsperf.com/test-parseint-and-math-floor