JavaScript 排序算法实践与优化

101 阅读2分钟

引言

JavaScript 是一门广泛使用的语言,为前端开发者和 Web 开发者所钟爱。其中一项重要任务是组织、处理和排序数据。在本篇文章中,我们将关注 JavaScript 中的常见排序算法,通过代码示例来进行解析。

JavaScript 内置排序算法

JavaScript 提供了一个内置方法 Array.prototype.sort(),可以对数组执行原地排序,不产生新的数组。默认情况下,这种排序是基于字符串的 Unicode 编码。这就意味着,数组中的数字将首先转换为字符串,然后进行比较。

const numbers = [10, 5, 8, 1, 7];
numbers.sort(); 
console.log(numbers); // 输出:[1, 10, 5, 7, 8],由于先转换成字符串,所以存在问题

对于数字数组,我们可以提供一个可选的比较函数来获得正确的排序结果。

const numbers = [10, 5, 8, 1, 7];
numbers.sort((a, b) => a - b);
console.log(numbers); // 输出:[1, 5, 7, 8, 10]

然而,对于大量数据或更复杂的排序需求,我们可能需要使用更高效的排序算法。

冒泡排序

冒泡排序是一种简单的排序算法,逐个遍历数组,将相邻的两个数进行比较,将较大的数移动到正确的位置。因为每次循环遍历都会使较大的数上浮至正确位置,因此被称为“冒泡排序”。

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

const numbers = [10, 5, 8, 1, 7];
console.log(bubbleSort(numbers)); // 输出:[1, 5, 7, 8, 10]

冒泡排序的时间复杂度为 O(n²),并不适用于大型数据集。

快速排序

快速排序是一种更高效的排序算法。它的工作原理是选择一个‘基准’元素,将小于基准的元素移到它的左边,将大于基准的元素移到它的右边。然后对左侧和右侧子数组分别递归执行该操作。快速排序的平均时间复杂度为 O(n * log(n))。

function quickSort(arr) {
  if (arr.length <= 1) return arr;

  const pivotIndex = Math.floor(arr.length / 2);
  const pivot = arr.splice(pivotIndex, 1)[0];
  const left = [];
  const right = [];

  for (let i = 0; i < arr.length; i++) {
    if (arr[i] < pivot) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }

  return quickSort(left).concat([pivot], quickSort(right));
}

const numbers = [10, 5, 8, 1, 7];
console.log(quickSort(numbers)); // 输出:[1, 5, 7, 8, 10]

尽管快速排序在某些情况下可能会退化为 O(n²) 复杂度,但它在许多情况下(特别是大型数据集)的效果都要优于冒泡排序。

结论

在JavaScript中,我们可以使用内置的 Array.prototype.sort() 方法进行排序,但要记住这种排序默认是基于字符串的。在许多情况下,为 sort() 提供一个比较函数可以得到正确的结果,但在大型数据集中可能需要更高效的排序算法,如冒泡排序或快速排序。每种排序算法都有其优缺点,可以根据具体需求选择适当的算法。