究极短的快排代码【QuickSort】

快排 QuickSort

两边向中间扫描法:取一个基点值,从左往右扫描,基点值左边所有元素小于它,遇到大于基点值的则停下,开始从右往左扫描,右边所有元素大于他,遇到小于基点值则停下,如果这时左右指针不交叉(左指针在基点左边,右指针在基点右边),则交换两个指针当前值,在每一次交换后两个指针均向右向左移动。依次递归则完成排序。

取中间值为基点,如果递归调用时将j换成i,那么x取值时需要向上取整,否则会造成边界问题

建议读者用不同的数组根据代码逻辑模拟 方便理解

void QuickSort(int a[] , int l , int r){
    if ( l >= r ) return ;
    int i = l - 1, j = r + 1, x = a[l + r >> 1] ; //注意x的取值与下面的函数递归调用的参数有关
    while( i < j ){
        while( a[++i] < x );
        while( a[--j] > x );
        if( i < j ) swap(a[i] , a[j]);
    }
    QuickSort(a , l , j);
    QuickSort(a , j + 1 , r);
}

void QuickSort(int a[] , int l , int r){
    if ( l >= r ) return ;
    int i = l - 1, j = r + 1, x = a[l + r + 1 >> 1] ; //注意x的取值与下面的函数递归调用的参数有关
    while( i < j ){
        while( a[++i] < x );
        while( a[--j] > x );
        if( i < j ) swap(a[i] , a[j]);
    }
    QuickSort(a , l , i - 1);
    QuickSort(a , i , r);
}

当给的序列元素全都一样时以下两种写法时间复杂度会退化到O(n 2)

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

求第K小元素

int QuickSort(int a[] , int l , int r , int k)
{
    if(l == r) return a[l];
    int x = a[l];
    int i = l - 1 , j = r + 1;
    while(i < j){
        while( a[++i] < x );
        while( a[--j] > x );
        if(i < j) swap(a[i],a[j]);
    }
    int len = j - l + 1;
    if( k <= len) return QuickSort(a, l , j , k);
    return QuickSort(a, j+1 , r , k - len);
}

求第K大元素

int QuickSort(int a[] , int l , int r , int k)
{
    if(l == r) return a[r];
    int x = a[r];
    int i = l-1 , j = r + 1;
    while(i<j){
        while(a[++i] < x);
        while(a[--j] > x);
        if(i < j) swap(a[i],a[j]);
    }
    int len = r - i + 1;
    if( k >= len) return QuickSort(a, l , i - 1 , k - len);
    return QuickSort(a, i , r , k);
}