JavaScript实现快速排序

快速排序的思想:在数组中找到一个基准数(pivot),然后将数组分为2部分,左边的数比基准数小,右边的数比基准数大,然后继续对左右区间进行同样操作,直到各个区间剩下1个数,就能够产生有序的数组了。

性能分析:最差的情况下,每次选取的基准数都是区间最大或最小值,导致每次只划分一个区域,需要n-1次递归才能结束排序,这时候的时间复杂度为O(n^2);

                  最好的情况下,每次选取的基准数都是区间的中间值,每次都划分2个区间,那就需要进行log n次递归才能结束排序,这时候的时间复杂度为O(nlog n),平均情况下,时间复杂度为O(nlog n)。快速排序是不稳定的,需要的辅助空间为O(nlog n)

当数组基本有序的时候,快排就没有什么优势,基本退化为冒泡排序,可以对基准数的选取进行优化,尽量选取中间值。

第一种实现方案:

function quickSort(arr,left,right){
  if(left = right) return;
  let index = partition(pivot,left,right);//选取key下标
  if(left<key){
    quickSort(arr,left,index-1)//对左部分进行排序
  }
  if(key<right){
    quickSort(arr,index+1,right)//对右部分进行排序
  }
}
function partition(arr,left,right){
  let key=arr[left];//让key等于左边第一个数
  while(left<right){//遍历一遍
    while(key<=arr[right] && left<right){//如果key比a[right]小,则右边递减,继续比较
      right--;
    }
    [arr[left],arr[right]] = [arr[right],arr[left]]//交换
     while(key>=arr[left] && left<right){//如果key比arr[left]大,则左边递增,继续比较
      left++;
    }
    [arr[left],arr[right]] = [arr[right],arr[left]]//交换
  }
  return left;//返回key的下标
}

对基准数的切分一般有3种方法,固定切分,随机切分,三取样切分。固定切分的效率不好,常用的是随机切分,但是最坏的情况也会出现O(n^2),建议使用三取样切分。

function quickSort(arr,left,right){
  if(left = right) return;
  let index = partition(arr,left,right)
  if(left<key){
    quickSort(arr,left,index-1)
  }
  if(key<right){
    quickSort(arr,index,right)
  }
}
function partition(){
  let key = getKey(arr,left,right);
  while(left<right){
    while(key<=arr[right] && left<right){
      right--
    }
    exchange(arr,left,right)
    while(key>=arr[left] && left<right){
      left++
    }
    exchange(arr,left,right)
  }
  return left;
}
function getKey(arr,left,right){
  let mid = arr[Math.floor((left+right)/2)];
  if(a[mid]>a[right]){exchange(arr,mid,right)};
  if(a[left]>a[right]){exchange(arr,left,right)};
  if(a[mid]>a[left]){exchange(arr,left,right)};
  let key = arr[left]//现在arr[mid]<arr[left]<arr[right]
  return key;
}
function exchange(arr,a,b){
  [arr[a],arr[b]]=[arr[b],arr[a]]
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值