js算法——快速排序与快速选择

快速排序

  1. 创建用于交换数组两个值的函数swap
  2. 创建quick快速排序函数,入参i为起始下标,j为末尾下标
  3. 我们将起始下标i对应的arr[i]值作为基准,声明两个哨兵lr分别代表左侧哨兵和右侧哨兵,初始位于起始下标和末尾下标。
  4. r向左侧移动,寻找到第一个小于(若降序则相反基准的值;l向右侧移动,寻找到第一个大于(若降序则相反基准的值,找到后交换,并继续找下一对值交换,寻找条件要确保左侧哨兵和右侧哨兵没有相遇:l<r
  5. 当哨兵相遇时,将相遇点的值基准值交换,得到的相遇点的值为基准中心,左侧的值一定小于它,右侧的一定大于它。
  6. 将相遇点左侧与右侧继续递归,递归条件为基准中心左侧l-1下标值大于起始下标i,也就是相遇点左侧至少存在两个数,右侧同理,递归完毕,值从小到大进行排序。
   //对应解释1
   const swap=(arr,a,b)=>{
       [arr[a],arr[b]]=[arr[b],arr[a]]
   }
   //对应解释2
   const quick=(arr,i,j)=>{
      //对应解释3
      let l=i,r=j
      //对应解释4
      while(l<r){
          while(l<r&&arr[r]>=arr[i]) r--
          while(l<r&&arr[l]<=arr[i]) l++
          swap(arr,l,r)
      }
      //对应解释5
      swap(arr,i,l)
      //对应解释6
      if(l-1>i){
        quick(arr,i,l-1)
      }
      if(l+1<j){
        quick(arr,l+1,j)
      }
   }
   quick(arr,0,arr.length-1)

快速选择

  1. 例如寻找前k个最小的数,快速排序时左侧值会小于基准中心,因此每次找到基准中心如果基准中心:
    等于k则已经找到前k个最小值了,返回前k个即可;
    大于k,则右侧数排除,继续排序左侧即可;
    小于k,则左侧数已经在前k个最小值的范围内了,顺序无所谓,继续排序右侧。
   const swap=(arr,a,b)=>{
       [arr[a],arr[b]]=[arr[b],arr[a]]
   }
   const quick=(arr,i,j)=>{
      let l=i,r=j
      while(l<r){
          while(l<r&&arr[r]>=arr[i]) r--
          while(l<r&&arr[l]<=arr[i]) l++
          swap(arr,l,r)
      }
      swap(arr,i,l)
      
      //对应解释
      if(l===k){
         return arr.slice(0,k)
      }else if(l>k){
         return quick(arr,i,l-1)
      }else {
         return quick(arr,l+1,j)
      }
      
   }
   const res= quick(arr,0,arr.length-1)
  1. 例如寻找第k个大的数,降序排序的话快速排序时左侧值会大于基准中心,因此每次找到基准中心如果基准中心:
    等于k-1则已经找到那个第k个(arr[k-1])大的数了,返回即可;
    大于k-1,则第k大的数必定在左侧,右侧数全排除,继续排序左侧即可;
    小于k-1,则左侧数(不超过k个)是都大于第k大的数,顺序无所谓直接排除,继续排序右侧。
   const swap=(arr,a,b)=>{
       [arr[a],arr[b]]=[arr[b],arr[a]]
   }
   const quick=(arr,i,j)=>{
      let l=i,r=j
      while(l<r){
          while(l<r&&arr[r]>=arr[i]) r--
          while(l<r&&arr[l]<=arr[i]) l++
          swap(arr,l,r)
      }
      swap(arr,i,l)
      
      //对应解释
      if(l===k-1){
         return arr[k-1]
      }else if(l>k-1){
         return quick(arr,i,l-1)
      }else {
         return quick(arr,l+1,j)
      }
      
   }
   const res= quick(arr,0,arr.length-1)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在下月亮有何贵干

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值