Array#sort()
ฟังก์ชันJavaScript ใดที่ใช้อัลกอริทึม ฉันเข้าใจว่ามันสามารถใช้การโต้แย้งและฟังก์ชั่นในการดำเนินการประเภทต่าง ๆ ได้ฉันสนใจในอัลกอริธึมที่การเรียงลำดับวานิลลาใช้
Array#sort()
ฟังก์ชันJavaScript ใดที่ใช้อัลกอริทึม ฉันเข้าใจว่ามันสามารถใช้การโต้แย้งและฟังก์ชั่นในการดำเนินการประเภทต่าง ๆ ได้ฉันสนใจในอัลกอริธึมที่การเรียงลำดับวานิลลาใช้
คำตอบ:
หากคุณดูที่ข้อผิดพลาด224128นี้ดูเหมือนว่า Mozilla จะถูกใช้งาน MergeSort
ฉันเพิ่งได้ดู WebKit ที่ (Chrome, Safari ... ) แหล่งที่มาแหล่งที่มาขึ้นอยู่กับประเภทของอาเรย์จะใช้วิธีการเรียงลำดับที่แตกต่างกัน:
อาร์เรย์ที่เป็นตัวเลข (หรืออาร์เรย์ของชนิดดั้งเดิม) จะถูกจัดเรียงโดยใช้ฟังก์ชันไลบรารีมาตรฐาน C ++ std::qsort
ซึ่งใช้การเปลี่ยนแปลงบางอย่างของ quicksort (โดยปกติแล้วจะเป็นintrosort )
อาร์เรย์ที่ต่อเนื่องกันของประเภทที่ไม่ใช่ตัวเลขจะมีการทำให้เป็นสตริงและเรียงลำดับโดยใช้การผสานถ้ามี (เพื่อให้ได้การเรียงที่เสถียร) หรือqsort
ผสานหากไม่มีการเรียงแบบผสาน
สำหรับประเภทอื่น ๆ (อาเรย์ที่ไม่ต่อเนื่องกันและน่าจะเป็นอาเรย์แบบเชื่อมโยง) WebKit ใช้การเรียงลำดับการเลือกอย่างใดอย่างหนึ่ง(ซึ่งเรียกว่าการเรียงลำดับ "ต่ำสุด") ) หรือในบางกรณีมันเรียงลำดับผ่านแผนผัง AVL น่าเสียดายที่เอกสารที่นี่ค่อนข้างคลุมเครือดังนั้นคุณต้องติดตามเส้นทางของรหัสเพื่อดูว่าประเภทใดที่ใช้วิธีการเรียงลำดับ
และจากนั้นก็มีอัญมณีเช่นความคิดเห็นนี้ :
// 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).
- เราหวังว่าผู้ที่ "แก้ไข" จริง ๆ แล้วสิ่งนี้จะมีความเข้าใจที่ดีขึ้นเกี่ยวกับการทำงานของ asymptotic รันไทม์มากกว่าผู้เขียนความคิดเห็นนี้และตระหนักว่าการเรียงลำดับของ radix นั้นมีคำอธิบายรันไทม์ที่ซับซ้อนเล็กน้อยกว่า O (N)
(ขอบคุณ phsource ที่ชี้ให้เห็นข้อผิดพลาดในคำตอบเดิม)
ไม่มีข้อกำหนดแบบร่างสำหรับ JS เพื่อใช้การจัดเรียง algorthim เฉพาะ ดังที่หลายคนกล่าวถึงที่นี่ Mozilla ใช้การผสานการเรียงลำดับอย่างไรก็ตามในซอร์สโค้ด v8 ของ Chrome ณ วันนี้มันใช้ QuickSort และ InsertionSort สำหรับอาร์เรย์ขนาดเล็ก
จากสาย 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;
}
}
};
อัปเดต ตั้งแต่ปี 2018 V8 ใช้ TimSort ขอบคุณ @celwell แหล่ง
มาตรฐาน ECMAscript ไม่ได้ระบุอัลกอริทึมการเรียงลำดับที่จะใช้ เบราว์เซอร์ที่แตกต่างกันนั้นมีอัลกอริทึมการเรียงลำดับที่แตกต่างกัน ตัวอย่างเช่นการเรียงลำดับของ Mozilla / Firefox () ไม่เสถียร (ในแง่การเรียงลำดับของคำ) เมื่อเรียงลำดับแผนที่ การจัดเรียงของ IE () มีเสถียรภาพ
ฉันคิดว่ามันจะขึ้นอยู่กับการใช้งานเบราว์เซอร์ที่คุณอ้างถึง
เบราว์เซอร์ทุกประเภทมีเครื่องมือติดตั้งจาวาสคริปต์เป็นของตัวเอง คุณสามารถตรวจสอบซอร์สโค้ด repos สำหรับ Mozilla และ Webkit / Khtml สำหรับการใช้งานที่แตกต่างกัน
อย่างไรก็ตาม IE เป็นแหล่งปิดดังนั้นคุณอาจต้องถามใครสักคนที่ microsoft
ตั้งแต่ V8 v7.0 / Chrome 70 V8 ใช้TimSortซึ่งเป็นอัลกอริธึมในการเรียงของ Python Chrome 70 วางจำหน่ายในวันที่ 13 กันยายน 2018
ดูโพสต์ในบล็อกของนักพัฒนา V8สำหรับรายละเอียดเกี่ยวกับการเปลี่ยนแปลงนี้ นอกจากนี้คุณยังสามารถอ่านรหัสที่มาหรือแก้ไข 1186801
ฟังก์ชัน Array.sort () ของ JavaScript มีกลไกภายในเพื่อเลือกอัลกอริทึมการเรียงลำดับที่ดีที่สุด (QuickSort, MergeSort และอื่น ๆ ) บนพื้นฐานของประเภทข้อมูลขององค์ประกอบอาร์เรย์
ลองใช้การเรียงลำดับด่วน:
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);
}