Javascript的Array.sort实现?
JavaScript Array#sort()
函数使用哪种algorithm? 我明白,它可以采取各种各样的论据和function来执行不同种类的分类,我只是对香草类使用哪种algorithm感兴趣。
如果你看看这个bug 224128 ,看起来MergeSort正在被Mozilla使用。
我刚看了一下WebKit(Chrome,Safari …)的源码 。 根据数组的types,使用不同的sorting方法:
数字数组 (或原始types的数组)使用C ++标准库函数std::qsort
进行sorting,该函数执行quicksort (通常为introsort )的一些变体。
非数字types的连续数组被串化并使用mergesort进行sorting(如果可用的话)(获得稳定的sorting)或qsort
如果没有合并sorting可用)。
对于其他types(非连续数组和大概是关联数组),WebKit使用selectsorting (他们称之为“min”sorting ),或者在某些情况下,通过AVL树sorting。 不幸的是,这里的文档相当模糊,所以你必须跟踪代码path才能真正看到哪种types的sorting方法被使用。
然后有这样的评论gem:
// 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).
– 让我们只希望那些真正“修复”的人比这个注释的作者对渐近运行时有更好的理解,并且意识到基数sorting比O(N) 有更复杂的运行时描述 。
(感谢phsource在原始答案中指出错误。)
ECMAscript标准没有指定要使用哪种sortingalgorithm。 事实上,不同的浏览器具有不同的sortingalgorithm。 例如,sorting地图时,Mozilla / Firefox的sort() 不稳定 (在sorting意义上)。 IE的sort()是稳定的。
JS没有草案要求使用特定的sortingalgorthim。 正如很多人在这里提到的,Mozilla使用合并sorting。然而,在Chrome的v8源代码中,到目前为止,它使用QuickSort和InsertionSort,用于更小的arrays。
https://github.com/v8/v8/blob/master/src/js/array.js
从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; } } };
经过一些更多的研究,对于Mozilla / Firefox来说,Array.sort()使用mergesort。 看到这里的代码。
我认为这将取决于您引用的浏览器实现。
每个浏览器types都有它自己的JavaScript引擎实现,所以它取决于。 您可以检查Mozilla和Webkit / Khtml的源代码库,以获取不同的实现。
IE是封闭的源代码,所以你可能不得不问微软的人。