У мене є відсортований масив JavaScript, і хочу вставити ще один елемент у масив, таким чином отриманий масив залишається відсортованим. Я, безумовно, міг реалізувати просту функцію вставки в стилі 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));
[ПОПЕРЕДЖЕННЯ] цей код має помилку при спробі вставити на початок масиву, наприклад insert(2, [3, 7 ,9]) видає неправильні [3, 2, 7, 9].
Однак я помітив, що реалізація функції Array.sort потенційно може зробити це для мене, і в основному:
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));
Чи є вагомі підстави вибрати першу реалізацію над другою?
Редагувати : Зауважте, що для загального випадку вставка O (log (n)) (як реалізовано в першому прикладі) буде швидшою, ніж алгоритм загального сортування; однак це не обов'язково стосується JavaScript, зокрема. Зауважте, що:
- Найкращим випадком для декількох алгоритмів вставки є O (n), який все ще суттєво відрізняється від O (log (n)), але не настільки поганий, як O (n log (n)), як зазначено нижче. Це зводиться до конкретного алгоритму сортування (див. Реалізацію Javascript Array.sort?) )
- Метод сортування в JavaScript - це основна функція, тому потенційно реалізуючи величезні переваги - O (log (n)) з величезним коефіцієнтом, все ще може бути набагато гіршим, ніж O (n) для наборів даних досить розміру.
splice()(наприклад, ваш перший приклад), вже є O (n). Навіть якщо він не створює внутрішньо нову копію всього масиву, він, можливо, повинен перемістити всі n елементів назад 1 позицію, якщо елемент потрібно вставити в позицію 0. Можливо, це швидко, тому що це нативна функція, а константа - низький, але все-таки O (n).
parseIntвикористовуйте Math.floorнатомість використання . Math.floorнабагато швидше, ніж parseInt: jsperf.com/test-parseint-and-math-floor