# Javascript Array.sort实现？

2020/10/11 11:21 · javascript ·  · 0评论

JavaScript`Array#sort()`函数使用哪种算法我知道可以使用各种形式的参数和函数来执行不同种类的排序，我只是对香草排序使用哪种算法感兴趣。

``````// 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).
``````

–我们只希望真正“解决”此问题的人比这篇评论的作者对渐近运行时有更好的理解，并意识到基数排序比简单的O（N）稍微复杂一些。

（感谢phsource指出了原始答案中的错误。）

JS没有使用特定排序算法的草稿要求。正如许多人在这里提到的那样，Mozilla使用合并排序，但是在Chrome的v8源代码中，直到今天，对于较小的数组，它都使用QuickSort和InsertionSort。

V8引擎来源

``````  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;
}
}
};
``````

ECMAscript标准未指定要使用哪种排序算法。实际上，不同的浏览器具有不同的排序算法。例如，Mozilla / Firefox的sort（）在对地图进行排序时不稳定（按单词的排序意义）。IE的sort（）是稳定的。

IE是封闭源，因此，您可能必须向Microsoft咨询。

JavaScript的Array.sort（）函数具有内部机制，可以根据数组元素的数据类型选择最佳的排序算法（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);
}
``````