快排就是找一个基数用来比较
把比他大的放他前面,比他小的放他后面
然后把前后两部分重复此方法排序
let list = [2, 3, 1, 9, 5, 6, 4, 7, 8];
let quick = function(arr) {
if (arr.length < 1) {
return arr;
}
let base = arr[0], left = [], right = [];
for (let i = 1; i < arr.length; i++) {
if (arr[i] < base) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
return arguments.callee(left).concat(base, quick(right))
}
let result = quick(list);
console.log(result)
这个方法比较简单,直接创建数组,把比基数小的放前面数组,大的放后面数组。然后利用数组合并就是排序后的数组。但是重复创建了很多数组对象,加上递归的原因,这里对性能是一种严重的浪费。
let quickSort = function(arr, startIndex, endIndex) {
if (startIndex > endIndex) {
return;
}
let left = startIndex, right = endIndex, base = list[startIndex];
while (left !== right) {
while (right > left && arr[right] >= base) {
right--;
}
while (left < right && arr[left] <= base) {
left++;
}
if (left < right) {
let temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
}
arr[startIndex] = arr[right];
arr[right] = base;
arguments.callee(arr, startIndex, left - 1);
arguments.callee(arr, left + 1, endIndex)
}
quickSort(list, 0, list.length - 1);
console.log(list)
right
指向右边第一个比基数小的数。left
指向左边第一个比基数大的数。right
与left
碰头时,停止。因为此时left
遍历过的都是比基数小的,right
遍历过的都是比基数大的,没必要在找下去。right
指针停下来的数肯定是比基数小的数,因为这里基数是第一个,所以基数要与比它小的数换位置。left
停下的时候指向的是大于基数的数,要这个数没用,因为基数已经在第一个了,left
指向的数肯定在它后面,已经是正确的情况。如果我们取得基数是中间的某个值,这时候就得判断指针位置和数值大小再确定换不换位置。由于外层循环结束时right
位置使我们需要的位置,所以应该先从右往左开始找小的。如果先由左往右,left
指向一个比基数大的数停下了,这时候right
也与left
相遇了,但这时指向的数是比基数大的数,显然不是我们需要的。先从右开始就不一样了,right
锁定的是比基数小的,left
撞上right
时指向的数就是比基数小的数。right
与left
相遇,循环结束,将基数与right
指向的数换位。原文地址:https://www.cnblogs.com/wayshon/p/9275013.html