如何使用JavaScript实现快速排序算法

简介: 如何使用JavaScript实现快速排序算法

快速排序是一种常见的排序算法,在实际应用中使用广泛。它的时间复杂度是O(nlogn),相对于其他排序算法,它的执行效率更高。

快速排序算法的核心是分治思想,它将一个数组分成两个子数组,然后递归地对子数组进行排序,最终将整个数组排好序。

下面是使用JavaScript实现快速排序算法的代码实现:


function quickSort(arr) {
  if (arr.length <= 1) {
    return arr;
  }
  const pivot = arr[Math.floor(arr.length / 2)];
  const left = [];
  const right = [];
  for (let i = 0; i < arr.length; i++) {
    if (i === Math.floor(arr.length / 2)) {
      continue;
    }
    if (arr[i] < pivot) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }
  return [...quickSort(left), pivot, ...quickSort(right)];
}


上面的JavaScript代码实现了快速排序算法,首先判断传入的数组长度是否小于等于1,如果是,则直接返回该数组。否则,我们选择一个基准值(pivot)并将数组分成两个子数组,一个数组包含所有小于基准值的元素,另一个数组包含所有大于基准值的元素。然后,我们递归地对这两个子数组进行排序,并将它们与基准值合并起来。其中,我们使用了ES6的扩展语法来合并数组,如果你需要在旧版本的JavaScript中使用这个实现,你需要手动拼接数组。

除了使用中间元素作为基准值,还有其他选择基准值的方法,如随机选择、三数取中等。在实际应用中,根据具体情况选择不同的基准值选择方法可以提高算法的性能。此外,在实现过程中还可以使用其他优化策略,如尾递归优化、循环展开等,来提高算法的性能。 另外,在实现快速排序算法时,还有一些优化可以考虑。

  1. 第一个优化是针对基准值的选择。在前面的实现中,我们选择了数组中间的元素作为基准值。但是,如果数组已经有序,那么选择中间的元素作为基准值会导致快速排序算法的时间复杂度退化为O(n^2)。为了避免这种情况,可以采用三数取中(Median-of-three)的方法选择基准值。即在数组的开始、中间和结尾选取三个元素,然后选择其中值位于中间的元素作为基准值。
  2. 第二个优化是关于递归的实现方式。在前面的实现中,我们使用了递归来对子数组进行排序。但是,在递归深度过深的情况下,递归的开销可能会很大,甚至可能导致栈溢出。为了避免这种情况,可以使用迭代来替代递归,具体方法是使用一个栈(或队列)来存储待排序子数组的起始和结束下标,然后循环从栈(或队列)中取出一个子数组,对其进行排序,然后将左右子数组的起始和结束下标压入栈(或队列)中。

下面是使用JavaScript实现快速排序算法的优化代码实现:


function quickSort(arr) {
  const stack = [[0, arr.length - 1]];
  while (stack.length) {
    const [start, end] = stack.pop();
    if (end - start < 1) continue;
    const pivot = medianOfThree(arr, start, end);
    let left = start;
    let right = end;
    while (left <= right) {
      while (arr[left] < pivot) left++;
      while (arr[right] > pivot) right--;
      if (left <= right) {
        [arr[left], arr[right]] = [arr[right], arr[left]];
        left++;
        right--;
      }
    }
    stack.push([start, right]);
    stack.push([left, end]);
  }
  return arr;
}
function medianOfThree(arr, left, right) {
  const mid = left + Math.floor((right - left) / 2);
  if (arr[left] > arr[mid]) {
    [arr[left], arr[mid]] = [arr[mid], arr[left]];
  }
  if (arr[mid] > arr[right]) {
    [arr[mid], arr[right]] = [arr[right], arr[mid]];
    if (arr[left] > arr[mid]) {
      [arr[left], arr[mid]] = [arr[mid], arr[left]];
    }
  }
  return arr[mid];
}


在这个优化实现中,我们首先使用一个栈来存储待排序子数组的起始和结束下标。然后,每次从栈中取出一个子数组,使用三数取中的方法选择基准值,并使用双指针法进行排序。最后,将左右子数组的起始和结束下标


总结和思考


总结:


快速排序是一种高效的排序算法,它的时间复杂度为O(nlogn),相比其他排序算法,它更适用于大数据集的排序。

快速排序的核心思想是分治思想,它将一个数组分成两个子数组,递归地对子数组进行排序,最终将整个数组排序。

在实现快速排序算法时,需要注意基准值的选择,选择不同的基准值会影响算法的效率。同时,在递归实现时,需要注意边界条件和数组的合并方式。


思考:


快速排序算法的实现是相对简单的,但是它的效率却非常高。这是因为它使用了分治思想,将一个大问题分成两个小问题,然后递归地解决子问题。

另外,基准值的选择也很重要,一个好的基准值能够让算法的效率得到提高。通常情况下,选择数组中间的元素作为基准值是一个比较好的选择,但也有其他的选择方法,比如随机选择基准值或者选取三个元素取中间值等方法。

最后,快速排序算法虽然效率高,但也有一些缺点。当数据集较小时,快速排序算法的效率不如插入排序等简单排序算法。同时,在面对大量重复元素的情况下,快速排序算法的效率也会大打折扣。

因此,在实际应用中,需要根据具体情况选择不同的排序算法,并结合具体场景对算法进行优化。

目录
相关文章
|
22天前
|
JavaScript 算法 前端开发
JS算法必备之String常用操作方法
这篇文章详细介绍了JavaScript中字符串的基本操作,包括创建字符串、访问特定字符、字符串的拼接、位置查找、大小写转换、模式匹配、以及字符串的迭代和格式化等方法。
JS算法必备之String常用操作方法
|
22天前
|
JavaScript 算法 前端开发
JS算法必备之Array常用操作方法
这篇文章详细介绍了JavaScript中数组的创建、检测、转换、排序、操作方法以及迭代方法等,提供了数组操作的全面指南。
JS算法必备之Array常用操作方法
|
1月前
|
搜索推荐 算法 Java
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
该博客文章通过UML类图和Java源码示例,展示了如何使用适配器模式将QuickSort类和BinarySearch类的排序和查找功能适配到DataOperation接口中,实现算法的解耦和复用。
17 1
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
|
1月前
|
JavaScript 算法 前端开发
"揭秘Vue.js的高效渲染秘诀:深度解析Diff算法如何让前端开发快人一步"
【8月更文挑战第20天】Vue.js是一款备受欢迎的前端框架,以其声明式的响应式数据绑定和组件化开发著称。在Vue中,Diff算法是核心之一,它高效计算虚拟DOM更新时所需的最小实际DOM变更,确保界面快速准确更新。算法通过比较新旧虚拟DOM树的同层级节点,递归检查子节点,并利用`key`属性优化列表更新。虽然存在局限性,如难以处理跨层级节点移动,但Diff算法仍是Vue高效更新机制的关键,帮助开发者构建高性能Web应用。
39 1
|
2月前
|
JavaScript
JS【详解】快速排序
JS【详解】快速排序
31 1
JS【详解】快速排序
|
2月前
|
数据采集 算法 JavaScript
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法
JavaScript字符串搜索涵盖`indexOf`、`includes`及KMP算法。`indexOf`返回子字符串位置,`includes`检查是否包含子字符串。KMP是高效的搜索算法,尤其适合长模式匹配。示例展示了如何在数据采集(如网页爬虫)中使用这些方法,结合代理IP进行安全搜索。代码示例中,搜索百度新闻结果并检测是否含有特定字符串。学习这些技术能提升编程效率和性能。
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法
|
1月前
|
算法 搜索推荐
算法设计 (分治法应用实验报告)基于分治法的合并排序、快速排序、最近对问题
这篇文章是关于分治法应用的实验报告,详细介绍了如何利用分治法实现合并排序和快速排序算法,并探讨了使用分治法解决二维平面上的最近对问题的方法,包括伪代码、源代码实现及时间效率分析,并附有运行结果和小结。
|
2月前
|
算法 搜索推荐 编译器
算法高手养成记:Python快速排序的深度优化与实战案例分析
【7月更文挑战第11天】快速排序是编程基础,以O(n log n)时间复杂度和原址排序著称。其核心是“分而治之”,通过选择基准元素分割数组并递归排序两部分。优化包括:选择中位数作基准、尾递归优化、小数组用简单排序。以下是一个考虑优化的Python实现片段,展示了随机基准选择。通过实践和优化,能提升算法技能。**
47 3
|
2月前
|
算法 JavaScript
JS 【详解】树的遍历(含深度优先遍历和广度优先遍历的算法实现)
JS 【详解】树的遍历(含深度优先遍历和广度优先遍历的算法实现)
45 0
JS 【详解】树的遍历(含深度优先遍历和广度优先遍历的算法实现)
|
3月前
|
JavaScript 前端开发 搜索推荐
JavaScript常见的排序算法详解
JavaScript常见的排序算法详解
23 1