前端sort排序(前端排序 一文教你如何优化数组排序)

作者: jk2023-08-23 12:04:10
前端排序: 一文教你如何优化数组排序

数组排序是前端开发中常用的一个操作,通常情况下,JavaScript内置的sort()方法已经能够满足我们的需求,但是当处理大数据量或者需要自定义排序规则时,sort()方法可能会出现性能问题。本文将介绍如何通过优化数组排序的方式来提高排序的效率。

1. 传统的sort()方法存在的问题

sort()方法是JavaScript内置的数组排序方法,它的默认排序规则是将数组元素转换为字符串,并按照Unicode编码的顺序进行排序。例如,对于数字数组[3,6,1,9],默认的sort()方法排序后的结果为[1,3,6,9]。

虽然sort()方法能够解决大部分场景下的排序需求,但是它存在一些问题,如:

1.1 排序时无法保留原数组的顺序

对于需要保持原数组顺序的排序需求,sort()方法并不能满足。例如,对于数组[3, 6, 1, 9, 2],在第一次排序后,它的顺序变为了[1, 2, 3, 6, 9],也就是说原数组的顺序已经被改变,如果需要保持原数组顺序的话,就需要先对数组进行处理,再进行排序。

1.2 排序时无法自定义排序规则

对于一些自定义排序规则的需求,sort()方法往往无法满足。例如,对于对象数组[{name: \"Tom\", age: 18}, {name: \"Jim\", age: 20}, {name: \"Bob\", age: 16}],如果需要按照age从小到大排序,sort()方法就需要传入一个比较函数来实现,代码如下:

```javascript let arr = [{name: \"Tom\", age: 18}, {name: \"Jim\", age: 20}, {name: \"Bob\", age: 16}]; arr.sort((a, b) => { return a.age - b.age; }); console.log(arr); // [{name: \"Bob\", age: 16}, {name: \"Tom\", age: 18}, {name: \"Jim\", age: 20}] ```

虽然sort()方法可以自定义排序规则,但是当数据量较大时,比较函数的执行次数就会增加,从而影响排序的效率。

2. 常用的数组排序算法

在优化数组排序之前,我们需要了解一些常用的数组排序算法,常见的有:

2.1 冒泡排序

冒泡排序是一种相邻元素比较的排序算法,每经过一轮比较,将最大的元素逐渐向后移动,可以将数组按照从小到大排序。代码如下:

```javascript function bubbleSort(arr) { let len = arr.length; for (let i = 0; i < len - 1; i++) { for (let j = 0; j < len - i - 1; j++) { if (arr[j] > arr[j + 1]) { [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; } } } return arr; } ```

2.2 快速排序

快速排序是一种基于分治思想的排序算法,它的基本思路是通过一轮排序将数组分为两部分,一部分小于选定的“基准值”,另一部分大于选定的“基准值”,依次递归进行排序。代码如下:

```javascript function quickSort(arr) { if (arr.length <= 1) { return arr; } let pivot = arr[0]; let left = []; let right = []; for (let i = 1; i < arr.length; i++) { if (arr[i] < pivot) { left.push(arr[i]); } else { right.push(arr[i]); } } return quickSort(left).concat([pivot], quickSort(right)); } ```

快速排序的时间复杂度为O(nlogn),但是在最坏情况下,时间复杂度可能会退化为O(n^2)。

3. 优化数组排序的方法

针对sort()方法存在的问题,我们可以通过以下几种方法进行优化:

3.1 对sort()方法传入比较函数进行优化

当需要对数组进行自定义排序时,可以通过传入一个比较函数来优化sort()方法的性能。比较函数有两个参数a和b,如果a应该排在b的前面,则返回一个负数,如果a应该排在b的后面,则返回一个正数,如果a和b相等,则返回0。

例如,对于对象数组[{name: \"Tom\", age: 18}, {name: \"Jim\", age: 20}, {name: \"Bob\", age: 16}],如果需要按照age从小到大排序,可以通过以下代码实现:

```javascript let arr = [{name: \"Tom\", age: 18}, {name: \"Jim\", age: 20}, {name: \"Bob\", age: 16}]; arr.sort((a, b) => a.age - b.age); console.log(arr); // [{name: \"Bob\", age: 16}, {name: \"Tom\", age: 18}, {name: \"Jim\", age: 20}] ```

需要注意的是,每一次比较函数的执行次数为数组的长度,如果数据量过大,比较函数的执行次数就会增加,从而影响排序的效率。

3.2 使用冒泡排序进行优化

对于小规模的数组,使用冒泡排序可能比快速排序更加高效。因为冒泡排序只需要进行n-1轮比较,每轮比较只需要对相邻的两个元素进行比较。

例如,对于数组[3, 6, 1, 9, 2],可以通过以下代码使用冒泡排序进行排序:

```javascript function bubbleSort(arr) { let len = arr.length; for (let i = 0; i < len - 1; i++) { for (let j = 0; j < len - i - 1; j++) { if (arr[j] > arr[j + 1]) { [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; } } } return arr; } let arr = [3, 6, 1, 9, 2]; console.log(bubbleSort(arr)); // [1, 2, 3, 6, 9] ```

需要注意的是,冒泡排序的时间复杂度为O(n^2),数据量过大时,排序的效率就会大大降低。

3.3 使用快速排序进行优化

使用快速排序进行数组排序时,如果将数组元素乱序排列,就可能导致排序的时间复杂度退化为O(n^2)。因此,对于一个有序的数组或者近乎有序的数组,为了避免最坏情况的发生,可以通过以下优化方式进行快速排序:

3.3.1 三数取中法选择枢轴

在选择基准值时,可以通过三数取中法来提高基准值的选取精度。三数取中法的基本思想是,从序列的头、中、尾三个位置中选择一个关键字,当然是从小到大或从大到小排序决定。

```javascript function median3(arr, left, right) { let center = Math.floor((left + right) / 2); if (arr[left] > arr[center]) { [arr[left], arr[center]] = [arr[center], arr[left]]; } if (arr[left] > arr[right]) { [arr[left], arr[right]] = [arr[right], arr[left]]; } if (arr[center] > arr[right]) { [arr[center], arr[right]] = [arr[right], arr[center]]; } [arr[center], arr[right - 1]] = [arr[right - 1], arr[center]]; return arr[right - 1]; } function quickSort(arr, left, right) { if (left < right) { let pivot = median3(arr, left, right); let i = left; let j = right - 1; while (true) { while (arr[++i] < pivot) {} while (arr[--j] > pivot) {} if (i < j) { [arr[i], arr[j]] = [arr[j], arr[i]]; } else { break; } } [arr[i], arr[right - 1]] = [arr[right - 1], arr[i]]; quickSort(arr, left, i - 1); quickSort(arr, i + 1, right); } } ```

3.3.2 小数组采用插入排序

快速排序在较小区间的排序速度较慢,因此对于小数组,我们可以采用插入排序的方式来对其进行排序,从而提高排序的效率。

```javascript const INSERTION_SORT_THRESHOLD = 7; function quickSort(arr, left, right) { if (left + INSERTION_SORT_THRESHOLD <= right) { let pivot = median3(arr, left, right); let i = left; let j = right - 1; while (true) { while (arr[++i] < pivot) {} while (arr[--j] > pivot) {} if (i < j) { [arr[i], arr[j]] = [arr[j], arr[i]]; } else { break; } } [arr[i], arr[right - 1]] = [arr[right - 1], arr[i]]; quickSort(arr, left, i - 1); quickSort(arr, i + 1, right); } else { insertionSort(arr, left, right); } } function insertionSort(arr, left, right) { for (let i = left + 1; i <= right; i++) { let temp = arr[i]; let j = i - 1; while (j >= left && arr[j] > temp) { arr[j + 1] = arr[j]; j--; } arr[j + 1] = temp; } } let arr = [3, 6, 1, 9, 2, 8, 5, 4, 7]; quickSort(arr, 0, arr.length - 1); console.log(arr); // [1, 2, 3, 4, 5, 6, 7, 8, 9] ```

需要注意的是,在实际开发中,不同的算法优化方式适用于不同的场景,我们需要根据实际情况进行选择。

本文介绍了传统的sort()方法存在的问题,以及常见的数组排序算法和优化方案。在实际开发中,我们需要根据数据量和排序规则的不同,选择适合的排序算法和优化方式,从而提高排序的效率。

本文内容来自互联网,请自行判断内容的正确性。若本站收录的内容无意侵犯了贵司版权,且有疑问请给我们来信,我们会及时处理和回复。 转载请注明出处: http://www.bjdwkgd.com/redian/17784.html 前端sort排序(前端排序 一文教你如何优化数组排序)