描述
选中数组中的一个数当标识,让这个数组中左边的数都比这个数小,右边的元素都比这个元素大。
充分利用比较行为。
先把大数组排好序,再排小数组
正好与 归并排序 相反
代码
非原地排序
参考 阮一峰快速排序
//非原地排序
function quickSort1(arr) {
if (arr.length <= 1) return arr;
let pivot = arr.splice(Math.floor(arr.length / 2), 1)[0];
let left = [];
let right = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] < pivot) left.push(arr[i])
else right.push(arr[i])
}
return quickSort1(left).concat([pivot], quickSort1(right));
}
原地排序
就是将数组看成三部分,
第一部分是小于标识的元素,left下标表示第一部分的末尾
第二部分是等于标识的元素,left(不包括)与mid(不包括)中间的元素是等于标识的元素
第三部分是大于标识的元素,mid右边的元素是大于标识的元素
//原地排序
function quickSort(arr, l, r) {
//若左下标大于或等于右下标,没必要排序了,直接返回
if (l < r) {
let left = l - 1;
//mid永远标识还未进行比较的元素
let mid = l
let right = r;
//选择的标识是数组的最后一项
let pivot = arr[r]
while (mid < right) {
//元素小于标识,往第一部分添加元素
if (arr[mid] < pivot) {
swap(arr, ++left, mid++)
}
//元素大于标识,往第三部分添加元素
else if (arr[mid] > pivot) {
//之所以是--right是因为标识是最后一个元素,所以不用比较
swap(arr, --right, mid)
} else {
//元素等于标识,往第二部分添加元素,直接mid+1就好了
mid++;
}
}
//这一轮排序结束,将标识换到中间
swap(arr, mid, r);
//继续排序左边数组
quickSort(arr, l, left);
//继续排序右边数组
quickSort(arr, mid + 1, r);
} else {
return
}
}
//交换函数
function swap(arr, i, j) {
let t = arr[i];
arr[i] = arr[j]
arr[j] = t
}
若还是不理解可以看B站 左程云 的算法视频,在第二个视频中有讲解(用的是java)。