快速排序
快速排序也许是最常用的排序算法了。它的复杂度为O(nlog^n),且它的性能通常比其他的复杂度为O(nlogn)的排序算法要好。和归并排序一样,快速排序也使用分治的方法,将原始数组分为较小的数组(但它没有像归并排序那样将它们分割开)。
先上代码
class ArrayList{
constructor(){
this.array = []
}
insert(item){
this.array.push(item)
}
toString(){
return this.array.join()
}
swap(array,idx1,idx2){
[array[idx1],array[idx2]] = [array[idx2],array[idx1]] // ES6解构赋值
}
quickSort(){
this.quick(this.array,0,this.array.length-1)
}
quick(array,left,right){
var index;
if(array.length>1){
index = this.partition(array,left,right) // 划分
if(left<index-1){ // 需要特别注意递归时的left和right
this.quick(array,left,index-1)
}
if(index<right){ // 需要特别注意递归时的left和right
this.quick(array,index,right)
}
}
}
partition(array,left,right){
var pivot = array[Math.floor((left+right)/2)],l =left,r=right;
while(l<=r){ // 左小于右
while(array[l]<pivot){ // 找到左边的值比中间值大的索引值
l++
}
while(array[r]>pivot){ // 找到右边值比中间值小的索引值
r--
}
if(l<=r){
this.swap(array,l,r) // 如果左索引比右索引小,就交换这两个
l++;
r--;
}
}
return l;
}
}
先来看一个具体图例,这个就是划分操作的第一次执行。
执行完第一次后index为5,第二次执行时,执行的是this.quick(array,0,4)
,这时候的left为0,right为4
第三次执行时,因为这时候的l<right
,所以执行的是this.quick(array,1,4)
,这时候的left为1,right从上一步中获取是4
第四次递归时,获取上一步中的left和right分别为1,4,index为3,比较后执行this.quick(array,1,2)
此时在划分就是array=1了,也就是已经排好序了。那么就应该回到上一步了,获取上一步的index和right,此时left为2,比较后就执行this.quick(array,3,4)
;同样,此时在划分array也等于1了,因此在回到最初划分的时候了,那时候的index是5,right是array.legnth-1,再进行比较。