Javascript Array.sort implementation?

后端 未结 9 1692
难免孤独
难免孤独 2020-11-22 06:58

Which algorithm does the JavaScript Array#sort() function use? I understand that it can take all manner of arguments and functions to perform different kinds o

相关标签:
9条回答
  • 2020-11-22 07:46

    I think that would depend on what browser implementation you are refering to.

    Every browser type has it's own javascript engine implementation, so it depends. You could check the sourcecode repos for Mozilla and Webkit/Khtml for different implementations.

    IE is closed source however, so you may have to ask somebody at microsoft.

    0 讨论(0)
  • 2020-11-22 07:49

    try this with quick sort:

    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);
    }
    
    0 讨论(0)
  • 2020-11-22 07:51

    There is no draft requirement for JS to use a specific sorting algorthim. As many have mentioned here, Mozilla uses merge sort.However, In Chrome's v8 source code, as of today, it uses QuickSort and InsertionSort, for smaller arrays.

    V8 Engine Source

    From Lines 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;
          }
        }
      };
    

    Update As of 2018 V8 uses TimSort, thanks @celwell. Source

    0 讨论(0)
提交回复
热议问题