大多数人接触的第一个算法应该是大学时期在C语言课上学习的冒泡排序吧。刚好最近在练习算法题, 于是来回顾下排序算法中的快速排序。
快速排序的大致思路为:
- 确定数组中任意一项为基准数(一般取第一个)。
- 使用头尾双指针, 将比基准数大的移动到右侧, 小的移动到左侧。
- 对左右两侧重复上述步骤, 直至数组长度为1时停止。
综上所述, 我们在排序过程中会使用到递归, 并且递归终止条件为当前需要排序的数组分区长度为1。
代码如下:
/**
* @param arr 需要进行排序的原始数组
* @param start 需要进行排序的原始数组起始项的索引
* @param end 需要进行排序的原始数组结束项的索引
*/
const quickSort = (arr: number[], start: number = 0, end: number = arr.length - 1) => {
//定义头尾双指针
let left = start;
let right = end;
//确定递归结束条件
if (end - start < 1 || start < 0 || end < 0) {
return;
}
//定义基准值
const flag = arr[left];
//当两个指针没有相遇时, 进行循环处理移动数据
while (left !== right) {
// 从数组尾部开始, 比较当前项与基准值的大小, 若比基准值大, 则尾部指针前移
while (left !== right && arr[right] >= flag) right--;
//遇到较基准值小的项时, 结束上面的while循环, 将当前项赋值给当前的基准值所在的位置
arr[left] = arr[right];
// 从数组尾部开始, 比较当前项与基准值的大小, 若比基准值小, 则首部指针后移
while (left !== right && arr[left] <= flag) left++;
/**
* 当前帧 数组状态 :
* 1. arr[right]处的值与最开始定义的基准值位置的值是相同的, 且 arr[right] 处的值是一个无效值
* 2. arr[left]处的值是大于基准值的, 所以需要将该值直接赋值给 arr[right]
*/
arr[right] = arr[left];
}
//最后 结束的时候, 双指针会在同一个位置, 该位置前的值较基准值大, 位置后的值小较基准值小, 将基准值赋值给该位置
arr[left] = flag;
//对基准值左侧部分递归继续进行处理
quickSort(arr, start, left - 1);
//对基准值右侧部分递归继续进行处理
quickSort(arr, left + 1, end);
};