並べ替えられたJavaScript配列があり、結果の配列が並べ替えられたままになるように、配列に1つ以上の項目を挿入します。私は確かに単純なクイックソートスタイルの挿入関数を実装できました。
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));
2番目の実装よりも最初の実装を選択する十分な理由はありますか?
編集:一般的なケースでは、O(log(n))挿入(最初の例で実装されている)は、一般的な並べ替えアルゴリズムよりも高速です。ただし、これは特にJavaScriptの場合には必ずしも当てはまりません。ご了承ください:
- いくつかの挿入アルゴリズムの最良のケースは、O(n)です。これは、O(log(n))とはかなり異なりますが、以下で説明するように、O(n log(n))ほど悪くはありません。それは使用される特定のソートアルゴリズムに帰着します(Javascript Array.sort実装を参照してください?)
- JavaScriptのsortメソッドはネイティブ関数であるため、大きなメリットを実現できる可能性があります-巨大な係数を持つO(log(n))は、適度なサイズのデータセットの場合、O(n)よりもはるかに悪い可能性があります。
splice()
(たとえば、最初の例)はすでにO(n)です。配列全体の新しいコピーを内部で作成しなくても、要素を位置0に挿入する場合、n項目すべてを1ポジション分戻さなければならない可能性があります。ネイティブ関数であり、定数が低いですが、それでもO(n)です。
parseInt
使用しないでくださいMath.floor
。Math.floor
はるかに高速よりparseInt
:jsperf.com/test-parseint-and-math-floor