快速排序模板&边界条件分析

快速排序模板

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N];

void quickSort(int l, int r){
    if(l>=r) return;
    int mid=a[l+r>>1];
    int i=l-1, j=r+1;
    while(i<j){
        while(a[++i]<mid);
        while(a[--j]>mid);
        if(i<j) swap(a[i], a[j]);
    }
    quickSort(l,j);
    quickSort(j+1,r);
}

int main(){
    int n;
    cin>>n;
    for(int i=0; i<n; i++) cin>>a[i];
    quickSort(0,n-1);
    for(int i=0; i<n; i++) cout<<a[i]<<' ';
}

问题1 产生死循环

 while(a[++i]<mid);
 while(a[--j]>mid);
 // 上面两行替换为下面两行,导致死循环问题
 while(a[i]<mid) i++;
 while(a[j]>mid) j--;
  • 如果恰好出现 a[i]等于mid; a[j]等于mid的情况,下面的会产生死循环。
  • 上面采用++i,--j的写法,相当于使用do-while循环,避免了死循环。配合 i=l-1, j=r+1使用

问题2 子递归的划分---死递归问题

  • 死递归的原因是 (l,r)的递归空间,拆成了(l,l), (l,r)的空间,导致递归无法停止
  • 两种划分方案
      1. quickSort(l,j); quickSort(j+1,r); 不会发生死递归
      1. quickSort(l,i-1); quickSort(i,r); 会发生死递归
  • 分析可知,考虑参考轴的位置和边界的位置是否会重合?
  • 如果重合时,是否会发生最后跳出循环后 (i,边界l, 参考轴 3者重合的情况);或 (j, 边界r, 参考轴 3者重合的情况)---这是死递归发生的根源
    • 对于i划分,要避免l是参考轴,导致 i=l; 对于j划分,要避免r是参考轴导致 j=r; 由于 mid的选取为a[l+r>>1] 所以l~r只要有2个以上的数,参考轴不可能在r,也就不会死递归
posted @ 2025-04-13 14:52  Biang-Biang  阅读(89)  评论(0)    收藏  举报