Yanıtlar:
Bu hata 224128'e bakarsanız, MergeSort'un Mozilla tarafından kullanıldığı anlaşılıyor.
WebKit (Chrome, Safari…) kaynağına bir göz attım . Dizi türüne bağlı olarak farklı sıralama yöntemleri kullanılır:
Sayısal diziler (veya ilkel tip diziler), std::qsort
bazı hızlı sıralama çeşitlerini (genellikle introsort ) uygulayan C ++ standart kitaplık işlevi kullanılarak sıralanır .
Sayısal olmayan türdeki bitişik diziler , varsa (sabit bir sıralama elde etmek için) veya qsort
birleştirme sıralaması yoksa , mergesort kullanılarak dizilir ve sıralanır .
Diğer türler için (bitişik olmayan diziler ve büyük olasılıkla ilişkilendirilebilir diziler için) WebKit, seçim sıralaması kullanır ( "min" sıralama olarak adlandırır ) veya bazı durumlarda bir AVL ağacı aracılığıyla sıralar. Ne yazık ki, buradaki belgeler oldukça belirsizdir, bu nedenle hangi sıralama yönteminin kullanıldığını görmek için kod yollarını izlemeniz gerekir.
Ve sonra bu yorum gibi taşlar var :
// FIXME: Since we sort by string value, a fast algorithm might be to use a
// radix sort. That would be O(N) rather than O(N log N).
- Sadece bunu kim düzeltirse, bunun asimptotik çalışma zamanını bu yorumun yazarından daha iyi anladığını ve sayı tabanı sıralamasının sadece O (N) 'den biraz daha karmaşık çalışma zamanı açıklamasına sahip olduğunu fark edelim .
(Orijinal yanıttaki hatayı işaret ettiği için phsource sayesinde.)
JS'nin belirli bir sıralama algorthim kullanması için taslak şartı yoktur. Birçok kişinin burada belirttiği gibi, Mozilla birleştirme sıralaması kullanır.
Satırlardan 807-891
var QuickSort = function QuickSort(a, from, to) {
var third_index = 0;
while (true) {
// Insertion sort is faster for short arrays.
if (to - from <= 10) {
InsertionSort(a, from, to);
return;
}
if (to - from > 1000) {
third_index = GetThirdIndex(a, from, to);
} else {
third_index = from + ((to - from) >> 1);
}
// Find a pivot as the median of first, last and middle element.
var v0 = a[from];
var v1 = a[to - 1];
var v2 = a[third_index];
var c01 = comparefn(v0, v1);
if (c01 > 0) {
// v1 < v0, so swap them.
var tmp = v0;
v0 = v1;
v1 = tmp;
} // v0 <= v1.
var c02 = comparefn(v0, v2);
if (c02 >= 0) {
// v2 <= v0 <= v1.
var tmp = v0;
v0 = v2;
v2 = v1;
v1 = tmp;
} else {
// v0 <= v1 && v0 < v2
var c12 = comparefn(v1, v2);
if (c12 > 0) {
// v0 <= v2 < v1
var tmp = v1;
v1 = v2;
v2 = tmp;
}
}
// v0 <= v1 <= v2
a[from] = v0;
a[to - 1] = v2;
var pivot = v1;
var low_end = from + 1; // Upper bound of elements lower than pivot.
var high_start = to - 1; // Lower bound of elements greater than pivot.
a[third_index] = a[low_end];
a[low_end] = pivot;
// From low_end to i are elements equal to pivot.
// From i to high_start are elements that haven't been compared yet.
partition: for (var i = low_end + 1; i < high_start; i++) {
var element = a[i];
var order = comparefn(element, pivot);
if (order < 0) {
a[i] = a[low_end];
a[low_end] = element;
low_end++;
} else if (order > 0) {
do {
high_start--;
if (high_start == i) break partition;
var top_elem = a[high_start];
order = comparefn(top_elem, pivot);
} while (order > 0);
a[i] = a[high_start];
a[high_start] = element;
if (order < 0) {
element = a[i];
a[i] = a[low_end];
a[low_end] = element;
low_end++;
}
}
}
if (to - high_start < low_end - from) {
QuickSort(a, high_start, to);
to = low_end;
} else {
QuickSort(a, from, low_end);
from = high_start;
}
}
};
Güncelleme 2018 itibariyle V8, Timcelort kullanıyor, teşekkürler @celwell. Kaynak
ECMAscript standardı hangi sıralama algoritmasının kullanılacağını belirtmez. Aslında, farklı tarayıcılarda farklı sıralama algoritmaları bulunur. Örneğin, bir haritayı sıralarken Mozilla / Firefox'un sort () yöntemi (kelimenin sıralama anlamında ) sabit değildir . IE'nin sort () yöntemi kararlıdır.
Bu, hangi tarayıcı uygulamasından bahsettiğinize bağlı olacağını düşünüyorum.
Her tarayıcı türünün kendi javascript motoru uygulaması vardır, bu nedenle değişir. Mozilla için kaynak kodu depolarını ve farklı uygulamalar için Webkit / Khtml'yi kontrol edebilirsiniz.
IE kapalı kaynak kodludur, bu yüzden microsoft'ta birine danışmanız gerekebilir.
V8 v7.0 / Chrome 70 itibariyle V8 , Python'un sıralama algoritması olan TimSort'u kullanıyor . Chrome 70, 13 Eylül 2018'de piyasaya sürüldü.
Bkz V8 dev blogda yazı Bu değişiklikle ilgili ayrıntılar için. Ayrıca kaynak kodunu veya 1186801 yamasını da okuyabilirsiniz .
JavaScript'in Array.sort () işlevi, dizi öğelerinin veri türüne göre en iyi sıralama algoritmasını (QuickSort, MergeSort, vb.) Seçmek için dahili mekanizmalara sahiptir.
hızlı sıralama ile deneyin:
function sort(arr, compareFn = (a, b) => a <= b) {
if (!arr instanceof Array || arr.length === 0) {
return arr;
}
if (typeof compareFn !== 'function') {
throw new Error('compareFn is not a function!');
}
const partition = (arr, low, high) => {
const pivot = arr[low];
while (low < high) {
while (low < high && compareFn(pivot, arr[high])) {
--high;
}
arr[low] = arr[high];
while (low < high && compareFn(arr[low], pivot)) {
++low;
}
arr[high] = arr[low];
}
arr[low] = pivot;
return low;
};
const quickSort = (arr, low, high) => {
if (low < high) {
let pivot = partition(arr, low, high);
quickSort(arr, low, pivot - 1);
quickSort(arr, pivot + 1, high);
}
return arr;
};
return quickSort(arr, 0, arr.length - 1);
}