快速排序——C++实现

17 篇文章 2 订阅

快速排序采用“分治法”

首先选取一个“轴值”,假设数据中有k个数小于轴值,那么这k个数放在数组最左边的k个位置上,而不小于k的数放在数组右边的n-k个位置上。

这就实现了数组的一个“分割”。

给定分割中的值不必排序。只要求所有结点都被轴值正确分割。

快速排序再对已经分割的子序列继续进行类似分割。

下图演示了快速排序的执行过程:


源程序:

#include "stdio.h"  

template< class Elem >
void swap( Elem list[], int i, int j )
{
    Elem e_tmp = list[i];
    list[i] = list[j];
    list[j] = e_tmp;
}

// 如果以第一个或者最后一个为轴值,那么正序序列或逆序序列
// 的轴值的选择会使所有数分割到一边,影响排序性能
// 而选取随机值开销较大,中间值是不错的选择
int findpivot( int i_start, int i_end )  
{  
    return ( i_start + i_end ) / 2;
}

// 描述:
//      分别从头尾往中间移动,与轴值比较,
//      并且交换左右两边分别比轴值大和比轴值小的数
// 返回值:
//      右边分割序列第一的序号
template< class Elem >
int partition( Elem list[], int i_left, int i_right, Elem e_pivot )
{
    do
    {
        while ( list[++i_left] < e_pivot );
        while ( i_right > 0 && list[--i_right] > e_pivot );
        swap( list, i_left, i_right );
    }while ( i_left < i_right );

    // 纠正最后一次不必要的交换
    swap( list, i_left, i_right );

    // 此时i_left是右边第一个
    return i_left;
}
      
template< class Elem >  
int quicksort( Elem list[], int i_start, int i_end )
{
    // 递归 结束条件
    if ( i_end <= i_start )
        return 0;

    int i_pivot = findpivot( i_start, i_end );
    printf( "i_pivot: %d\n", i_pivot );

    // put pivot at end
    swap( list, i_pivot, i_end );

    // i_start要减1,便于在partition里先自减,再比较
    // i_end不需要减1,因为i_end本身已经为pivot
    int i_pivot_new = partition( list, i_start - 1, i_end, list[i_end] );
    printf( "i_pivot_new: %d\n", i_pivot_new );

    // put pivot at the right pivot position
    swap( list, i_end, i_pivot_new );

    quicksort( list, i_start, i_pivot_new - 1 );
    quicksort( list, i_pivot_new + 1, i_end );
    return 0;  
}  

  
int main()  
{  
    int p_srcarr[] = { 72, 6, 57, 88, 60, 42, 83, 73, 48, 85 }; 
    const int i_len = 10;  
    printf( "sizeof( p_srcarr ): %d", sizeof( p_srcarr ) );
    
    printf( "%s", "before quicksort\n" );  
    int i_index = 0;  
    for( i_index = 0; i_index < i_len; i_index ++ )  
    {  
        printf( "%4d", p_srcarr[i_index] );  
    }  
    printf( "%s", "\n" );  
  
    quicksort( p_srcarr, 0, i_len - 1 );
  
    printf( "%s", "after quicksort\n" );  
    for( i_index = 0; i_index < i_len; i_index ++ )  
    {  
        printf( "%4d", p_srcarr[i_index] );  
    }  
    printf( "%s", "\n" );
    
    return 0;  
}
快速排序平均时间代价为: Θ (nlogn)

参考:
《数据结构与算法分析》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值