这是我参与8月更文挑战的第19天,活动详情查看:8月更文挑战
快速排序
- 快速排序:使用分治的方法,将原始数组分为较小的数组。
- 核心思想:
- 首先,从数组中选择
中间一项
作为主元。 - 接着,(进行划分操作):
创建两个指针
,左边一个指向数组的第一项,右边一个指向数组的最后一项。 - 然后,移动
左指针
,直到找到一个比主元大
的元素;接着移动右指针
,找到一个比主元小
的元素。然后交换它们,重复这个过程,直到左指针超过了右指针。 - 在这个过程中会使得比主元小的元素,都排在主元之前,而比主元大的元素都排在主元之后。(划分操作结束)
- 然后,算法对划分之后的小数组(较主元小的元素组成的子数组,以及较主元大的元素组成的子数组),重复之前的步骤,直到数组已完全排序。
- 首先,从数组中选择
实现
// 我们先声明一个主方法来调用递归函数,传递待排序数组,以及索引0及其最末的位置
function quickSort(array) {
quick(array, 0, array.length -1)
}
// 实现quick递归函数
function quick(array, left, right) {
// 定义index来标记 主元位置
let index = null;
// 数组大于1才进行排序
if (array.length > 1) {
// 由主元位置计算函数 得出主元位置index的值,初始时左指针为0,右指针为length - 1
index = partition(array, left, right);
//
if (left < index -1) {
quick(array, left, index-1)
}
if (index < right) {
quick(array, index,right)
}
}
}
// 划分函数
function partition(array, left, right) {
// 首先。确定数组的中间下标的元素,作为主元
let pivot = array[Math.floor((left + right) / 2)];
// 初始化两个指针,分别是传进来的左指针0和右指针 length-1
let i = left;
let j = right;
// 只要 两个指针之间没有相互交错,就开始循环,否则返回 i
while(i <= j) {
// 移动左指针,直到找到一个元素比 主元 大
while(array[i] < pivot) {
i++
}
// 接着移动右指针,直到找到一个元素比 主元 小
while(array[j] > pivot) {
j--
}
// 当左指针指向的元素比主元大 且 右指针指向的元素 比主元小,同时,此刻的左指针索引小于等于右指针。也就是说左项比右项大,的时候
if(i <= j) {
// 交换两项的位置
let aux = array[i];
array[i] = array[j]
array[j] = aux;
// 移动指针,以便下次操作,重复此过程
i++
j--
}
}
// 整个划分结束之后,返回左指针的索引,用来创建子数组
return i
}