var quickSort = function(arr) {
if (arr.length <= 1) { return arr; }
var pivotIndex = Math.floor(arr.length / 2);
var pivot = arr.splice(pivotIndex, 1)[0];
var left = [];
var right = [];
for (var i = 0; i < arr.length; i++){
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return quickSort(left).concat([pivot], quickSort(right));
};
复制代码
这是从网上复制下来的快排。快排是利用到了递归,那么递归就是需要考虑空间复杂度。
先看,递归是怎么执行的
{
code()
{
code()
{
code()
{
code()
// 从最里面向外执行,而值是从外面一步步分解后传进来,那么系统就得保存好没一步被操作的值
}
}
}
}
复制代码
假设数据是占用100MB内存,那么运算过程储存的值也就会是100Mb,当然只会比这个多,就不细算,只要知道这个概念就好。
我们改进一下,直接在原数组上直接换值,而不用临时引用类型储存
var quickSort = function (arr) {
let len = arr.length
quickSortInternally(arr, 0, len-1)
// 递归
function quickSortInternally(arr, p, r) {
if(p>=r)return; // 数组长度等于1的时候结束递归
let q = partition(arr, p, r)
quickSortInternally(arr, 0, q-1)
quickSortInternally(arr, q+1, r)
}
// 获取区分点
function partition(arr, p, r) {
let i = p;
let pivot = arr[r] // 区分点
for(let j = i; j < r; j++){
if(arr[j]let tem = arr[j]
arr[j] = arr[i]
arr[i] = tem
++i
}
}
let tem = arr[r]
arr[r] = arr[i]
arr[i] = tem
return i;
}
}
复制代码
快排的最优状态才是O(nlogn),最坏状态是O(n2), 归并排序最好最坏都是O(nlogn),那么为什么js中的排序不用归并排序呢,就是因为归并不是原地排序,需要额外的内存空间。如果快排按照第一个那样写,那还是用归并排序把,因为第一个快排也不是原地排序。
快排的复杂度是看切分的深度,第二个写的快排区分点是那最后一个做区分点,如果数组是[1,2,3,4],这种顺序完成了或者接近完成的[1,3,2,4,5],这种就会O(n2)的时间复杂度。那么怎么解决这种问题。 我们可以取三点然后在取一个中间值(1,9,6;取6做区分点)。就会解决这种问题,直接尝试修改一下吧。 当然第二个参数再加一个fun参数,比较数组不都是[1,2,3]这样的,很多时候是[{},{},{}]这样的数据