`

javascript快速排序

 
阅读更多

Stable quicksort in Javascript

October 28th, 2008

Firefox < v3.0 doesn't have a stable Array.sort() function - that is, it doesn't maintain indexes for elements of equal value. This is undefined in the ECMA spec, and has been fixed in Firefox as of version 3 (and curiously enough has been stable in IE all along). As a result, I set out to find a stable, efficient Array.sort() replacement/supplement.

Mergesort is famous for being stable by design, and fast, though not terribly memory efficient. However, it uses a lot of code, and I couldn't manage to find a stable implementation of it.

After doing a little homework, I decided to modify this quicksort pseudocode to get the results I was after. Some would argue that quicksort's worst case performance is slower than mergesort, but for my purposes (small datasets) this was moot.

Here is the resulting code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// STABLE implementation of quick sort to replace unstable Array.sort method in Firefox
quickSort = function(arr) {
 
  // return if array is unsortable
  if (arr.length <= 1){
    return arr;
  }
 
  var less = Array(), greater = Array();
 
  // select and remove a pivot value pivot from array
  // a pivot value closer to median of the dataset may result in better performance
  var pivotIndex = Math.floor(arr.length / 2);
  var pivot = arr.splice(pivotIndex, 1)[0];
 
  // step through all array elements
  for (var x = 0; x < arr.length; x++){
 
    // if (current value is less than pivot),
    // OR if (current value is the same as pivot AND this index is less than the index of the pivot in the original array)
    // then push onto end of less array
    if (
      (arr[x] < pivot)
      ||
      (arr[x] == pivot && x < pivotIndex)  // this maintains the original order of values equal to the pivot
    ){
      less.push(arr[x]);
    }
 
    // if (current value is greater than pivot),
    // OR if (current value is the same as pivot AND this index is greater than or equal to the index of the pivot in the original array)
    // then push onto end of greater array
    else {
      greater.push(arr[x]);
    }
  }
 
  // concatenate less+pivot+greater arrays
  return quickSort(less).concat([pivot], quickSort(greater));
};

Of course, this will only sort an array of values (strings, numbers), so to sort an array of objects by a given property, I modified the above to produce:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// STABLE implementation of quick sort to replace unstable Array.sort method in Firefox
// if sorting an array of objects, key = name of object property to compare
// otherwise leave key undefined
quickSort = function(arr, key) {
 
  // return if array is unsortable
  if (arr.length <= 1){
    return arr;
  }
 
  var less = Array(), greater = Array();
 
  // select and remove a pivot value pivot from array
  // a pivot value closer to median of the dataset may result in better performance
  var pivotIndex = Math.floor(arr.length / 2);
  var pivot = arr.splice(pivotIndex, 1)[0];
 
  // step through all array elements
  for (var x = 0; x < arr.length; x++){
 
    // if (current value is less than pivot),
    // OR if (current value is the same as pivot AND this index is less than the index of the pivot in the original array)
    // then push onto end of less array
    if (
      (
        !key  // no object property name passed
        &&
        (
          (arr[x] < pivot)
          ||
          (arr[x] == pivot && x < pivotIndex)  // this maintains the original order of values equal to the pivot
        )
      )
      ||
      (
        key  // object property name passed
        &&
        (
          (arr[x][key] < pivot[key])
          ||
          (arr[x][key] == pivot[key] && x < pivotIndex)  // this maintains the original order of values equal to the pivot
        )
      )
    ){
      less.push(arr[x]);
    }
 
    // if (current value is greater than pivot),
    // OR if (current value is the same as pivot AND this index is greater than or equal to the index of the pivot in the original array)
    // then push onto end of greater array
    else {
      greater.push(arr[x]);
    }
  }
 
  // concatenate less+pivot+greater arrays
  return quickSort(less, key).concat([pivot], quickSort(greater, key));
};

Code samples

Now we can define an array of objects such as:

1
2
3
4
5
6
var objects = [
  {id: 1, type: 'fruit', name: 'apple', color: 'yellow'},
  {id: 2, type: 'vegetable', name: 'tomato', color: 'red'},
  {id: 3, type: 'fruit', name: 'apple', color: 'red'},
  {id: 4, type: 'vegetable', name: 'pepper', color: 'red'}
];

Then sort by color with a call to:

7
8
9
10
11
12
13
14
15
objects = quickSort(objects, 'color');
 
// sorted
objects = [
  {id: 2, type: 'vegetable', name: 'tomato', color: 'red'},
  {id: 3, type: 'fruit', name: 'apple', color: 'red'},
  {id: 4, type: 'vegetable', name: 'pepper', color: 'red'},
  {id: 1, type: 'fruit', name: 'apple', color: 'yellow'}
];

Then sort by type:

16
17
18
19
20
21
22
23
24
objects = quickSort(objects, 'type');
 
// sorted
objects = [
  {id: 3, type: 'fruit', name: 'apple', color: 'red'},
  {id: 1, type: 'fruit', name: 'apple', color: 'yellow'},
  {id: 2, type: 'vegetable', name: 'tomato', color: 'red'},
  {id: 4, type: 'vegetable', name: 'pepper', color: 'red'}
];

Then sort by name:

25
26
27
28
29
30
31
32
33
objects = quickSort(objects, 'name');
 
// sorted
objects = [
  {id: 3, type: 'fruit', name: 'apple', color: 'red'},
  {id: 1, type: 'fruit', name: 'apple', color: 'yellow'},
  {id: 4, type: 'vegetable', name: 'pepper', color: 'red'},
  {id: 2, type: 'vegetable', name: 'tomato', color: 'red'}
];
分享到:
评论

相关推荐

    JavaScript快速排序1

    JavaScript快速排序是一种高效的排序算法,基于分治策略。在快速排序中,我们首先选择一个基准值(pivot),然后重新组织数组,使得基准值左边的所有元素都比它小,右边的所有元素都比它大。这个过程叫做分区操作。...

    js代码-JavaScript 快速排序

    JavaScript 快速排序是一种高效的排序算法,由英国计算机科学家C.A.R. Hoare在1960年提出。它的基本思想是通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,然后分别对这...

    JavaScript实现快速排序(自已编写)

    简述: 用到javascript的排序一组数字,js没有直接的数字比较的函数可以调用,所以自己写了一个快速排序 知识点: 1. 正则表达式提取正负数字的string 2. str 转数字 放回列表 3. js的对象Sort类的声明及定义 4. ...

    Javascript快速排序算法详解

    具体到给定文件中的示例代码,它给出了快速排序的一个JavaScript实现。代码首先定义了一个partition函数,用于执行数组的分区操作;然后定义了一个sort函数,利用递归执行快速排序。最后,对一个数组实例进行排序,...

    javascript快速排序算法详解

    ### JavaScript实现快速排序 在JavaScript中,快速排序可以通过以下代码实现: ```javascript function quickSort(arr) { if (arr.length ) { return arr; // 数组长度小于等于1,不需要排序 } var pivot...

    javascript 快速排序函数代码

    快速排序是一种高效的排序算法,由C. A. R. Hoare在1960年提出。...上述提供的JavaScript代码实现了一个典型的快速排序算法。通过实践和理解这一算法,可以帮助开发者在处理大量数据时写出更高效的排序函数。

    Javascript实现快速排序(Quicksort)的算法详解

    以下是JavaScript实现快速排序算法的详细步骤: 1. **初始化**:首先,我们需要一个`quickSort`函数,它接收一个数组作为参数。如果数组长度小于或等于1,由于一个元素或无元素的数组已经是有序的,所以可以直接...

    快速排序(Quicksort)的Javascript实现

    快速排序(Quicksort)的Javascript实现 快速排序(Quicksort)是一种高效的排序算法,由图灵奖得主C. A. R. Hoare于1960年提出。该算法的思想很简单,整个排序过程只需要三步:(1)在数据集之中,选择一个元素...

    JavaScript希尔排序、快速排序、归并排序算法_.docx

    总结,JavaScript中的希尔排序、快速排序和归并排序都是在处理数组排序时常用的方法。希尔排序适用于中等规模数据,快速排序在平均情况下表现优秀,而归并排序则保证了稳定的O(n log n)时间复杂度,适合大数据量的...

    JavaScript-数据排序添加.rar

    在数据排序和添加的场景中,JavaScript可以用于处理数据结构,如数组,执行各种排序算法(如快速排序、冒泡排序、插入排序等),以及向数组中添加新元素。JavaScript提供了强大的数组方法,如`push()`用于添加元素,...

    javascript 实现排序分类功能

    javascript 实现排序分类功能, 冒泡排序, 快速排序等等

    JavaScript快速排序

    [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行] 代码如下:再你多快,你快不过Array.prototype.sort var a=[4,723,3,5,67,32,4,... 这才是最快的加个二叉树排序 [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

    11-6 JavaScript 实现:快速排序.mp4

    11-6 JavaScript 实现:快速排序.mp4

    Javascript表格排序大全

    JavaScript表格排序大全是一个涵盖多种JS表格排序实现方法的资源集合,旨在帮助开发者快速实现动态、交互式的表格数据排序功能。在网页开发中,表格是一种常用的数据展示方式,而JavaScript能够为表格提供强大的交互...

    通过实例解析JavaScript常用排序算法

    本文将深入探讨四种常见的排序算法:冒泡排序、快速排序、选择排序以及插入排序,并通过实例代码进行详细解析。 1. **冒泡排序**: 冒泡排序是最直观的排序算法之一,它通过重复遍历待排序的列表,比较每对相邻...

    javascript排序算法实现

    快速排序是一种分治策略的排序方法,通过选取一个基准值,将数组分为两部分,一部分的所有元素都小于基准,另一部分的所有元素都大于基准,然后对这两部分递归进行快速排序。快速排序的平均时间复杂度为O(n log n)...

Global site tag (gtag.js) - Google Analytics