Quicksort是计算机科学中对数组进行排序的最有效方法之一。 有关详细的分类,它有其自己的Wikipedia文章。
本文将介绍如何在JavaScript中实现quicksort。 Quicksort未内置在JavaScript中。 由于采用了Array原型的sort
方法,因此很少有人质疑或优化语言中的排序。 尽管如此,快速排序仍然是一个重要的算法,至少领悟 ,你是否不使用它。
它是如何工作的? 🤔
Quicksort的工作原理是从数组中选取一个元素并将其表示为“数据透视表”。 数组中的所有其他元素都分为两类-小于或大于此枢轴元素。
然后,将两个结果数组(值小于轴的值数组和值大于轴的值数组)中的每个数组通过同一算法进行处理。 选择一个枢轴,并将所有其他值分成小于和大于两个值的两个数组。
最终,子数组将包含单个值或根本不包含任何值,因为将没有更多的值可与之进行比较。 其余值在先前的某个点都被标记为“枢轴”,并且没有滴落到该最低子数组中。 到那时,这些值将被排序,因为所有值现在都声明为小于或大于数组中所有其他值。
我们如何实施呢? 💡
由于Array原型方法sort
使用其自己的排序算法,因此我们无法将其用于实现quicksort。 我们必须创建一个函数,该函数接收要排序的数组作为参数并返回sorted-array。
由于数组中项目的“值”可能不是立即显而易见的,因此我们应该为比较器提供一个可选参数。 对字符串或数字进行排序是内置在JavaScript中的,但对对象不进行排序。 我们可能想按年龄对一组用户对象( { name: 'Charles', age: 21 }
)进行排序。
由于我们可以将此数组划分为小于/大于一半的次数可以向无穷大变化,因此我们希望递归定义逻辑,以免重复代码(“选择枢轴,拆分,重复” )。
您可以使用任何索引作为枢轴位置:第一,中间,最后,随机。 假设数据是随机排序的,则枢轴的位置不会影响时间复杂度。 我将使用最后一个索引,因为这是Wikipedia在其演示图形中使用的,并且视觉效果与代码重合也很好。
枢轴前面的数组分为两个部分:小于正面的数组,大于末端的数组。 最后,枢轴本身在两个子数组之间移动,然后使用相同的快速排序算法对子数组进行排序。
我们将sortedArray
创建为新数组,以免使原始数组发生变异。 这不是必需的,但这是一个好习惯。
我们创建recursiveSort
作为递归函数,该函数将获取一个子sortedArray
(从开始索引到结束索引)并对其进行快速排序,从而使sortedArray
变化。 整个数组是要传递给此递归函数的第一个数组。
最后,返回排序后的数组。
recursiveSort
函数具有一个pivotValue
变量来表示我们的数据透视表的值,以及一个splitIndex
变量来表示界定小于和大于数组的索引。 从概念上讲,所有小于值的索引均小于splitIndex
而所有大于值的索引均大于splitIndex
。 splitIndex
初始化为子splitIndex
的开始,但是当发现小于枢轴值的值时,我们将相应地调整splitIndex
。
我们将遍历所有非枢轴值,将比枢轴值小的值移动到起始索引之前。
我们将所有小于枢轴值的值都移到splitIndex
并将所有其他值都保留在它们的位置(默认情况下,大于splitIndex
,因为split索引从子数组的开头开始)。
一旦子阵列已经重新排序,我们把支点本身的分裂,因为我们知道它是位于所有小于和大于或-等于对值之间 。
左边的所有值(从start
到splitIndex - 1
)将进行递归排序,右边的所有值(从splitIndex + 1
到end
)将进行递归排序。 现在, splitIndex
本身就是枢轴值,不再需要对其进行排序。
结论🔚
您可以在GitHub上的TypeScript中找到本文中的代码:
JavaScript / TypeScript中Quicksort的实现。 -CharlesStover / quicksort -js github.com
您也可以从NPM将以下代码添加到项目中:
如果您有任何疑问或相关见解,请发表评论。 快速,简单,免费!
要阅读更多专栏文章或与我联系,您可以在LinkedIn和Twitter上找到我,或者在CharlesStover.com上查看我的投资组合 。
From: https://hackernoon.com/implementing-quicksort-in-javascript-45cb83ab1aa0