js快速排序-(搬运+理解,从视频到文字)

视频理解
快排思想:

  1. 选定Pivot中心轴
  2. 大于Pivot的放到Pivot右边
  3. 小于Pivot的放到Pivot左边
  4. 分别对Pivot的左右子序列重复以上操作(直到序列长度为 1)
  • 阮一峰版本:https://www.cnblogs.com/hjx-blog/articles/9183453.html
    选取数组中间位置为 pivot,两个容器 left=[]right=[]。遍历数组,把小于 pivot 的放到 left 容器中;把大于 pivot 的放到 right 容器中哦。
    基线条件:
    当数组长度≤1,结束递归
    递归操作:
  1. 找到 pivot
  2. 从数组中删除pivot
  3. 遍历数组,把小于pivot的放到left,大于pivot的放到right
  4. 拼接 left,pivot,right
    **返回值:**拼接后的数组
let arr = [49,38,65,97,76,13,27,49];
function quicksort(arr){
  if(arr.length<=1) return arr;
  let pivotIndex = Math.floor(arr.length/2);
  let pivot = arr.splice(pivotIndex,1)[0];
  let [left,right] = [[],[]];
  for(let 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))
}
console.log(quicksort(arr))

时间复杂度:应该也是 O(NlogN)
空间复杂度:O(N)。每次都要开辟 left,right 两个空间。
问题:生产环境中,每次都要开辟额外的内存空间,不可。

注意:arr.spice(从哪个索引开始删,删几个,替换1,替换2,....)
arr.spice() 方法会改变原数组
返回值是被删除的元素组成的数组!

  • 快排面试版本:
function quickSort(arr,left,right){
  if(left>=right) return;//递归的基线条件
  let i=left,j=right;
  pivot = arr[left];
  while(i<j){//当 i<j 的时候,i,j 向中间靠拢,符合条件交换
    while(i<j&&arr[j]>=pivot){//j从右向左寻找比pivot小的数
      j--
    }
    while(i<j&&arr[i]<=pivot){//i从左往右寻找比pivot大的数
      i++
    }
    [arr[i],arr[j]] = [arr[j],arr[i]];//交换位置
  }//退出循环时,ij指向同一个数
  [arr[left],arr[i]] = [arr[i],arr[left]];//记得把pivot放到中间
  quickSort(arr,left,i-1);
  quickSort(arr,i+1,right);
  return arr;
}
console.log(quickSort(arr,0,arr.length-1))

时间复杂度:O(NlogN)。空间复杂度:原地交换,O(1)

快排复杂度
  • 最优:O(NlogN)。每次取到的元素刚好可以平分整个数组。 参考:

时间复杂度: T [ n ] = 2 T [ n / 2 ] + f ( n ) T[n] = 2T[n/2] + f(n) T[n]=2T[n/2]+f(n)
T[n/2] - 平分后,子数组所花费的时间复杂度;f(n) - 平分这个数组所花费的时间
第一次递归: T [ n ] = 2 T [ n / 2 ] + n T[n] = 2T[n/2] + n T[n]=2T[n/2]+n
第二次递归: T [ n ] = 2 ∗ 2 ( T [ n / 4 ] + n / 2 ) + f ( n ) T[n] = 2*2(T[n/4]+n/2) + f(n) T[n]=22(T[n/4]+n/2)+f(n) = 2 2 T [ n / 2 2 ] + 2 n 2^2T[n/{2^2}]+2n 22T[n/22]+2n
第三次递归: 2 3 T [ n / 2 3 ] + 3 n 2^3T[n/{2^3} ] + 3n 23T[n/23]+3n
第 m 次递归: 2 m T [ n / 2 m ] + m n 2^mT[n/{2^m} ] + mn 2mT[n/2m]+mn
到 T(1) 不能再分。所以 n / 2 m = 1 n/{2^m} =1 n/2m=1
m = l o g n m=logn m=logn
T[n] = 2^m T[1] + mn ;其中m = logn;
= nT[1] + nlogn = n + nlogn;根据曲线图,nlogn 远大于 n,所以取 nlogn

  • 最差: O ( N 2 ) O(N^2) O(N2)。每次取到的 pivot 是数组中最大/最小那个元素。这种情况就是冒泡排序了,每次只能排好一个元素的顺序。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值