闲来无事,温习一下快速排序法

  快速排序法,还是很常用的。不论是面试还是写代码。这里说一下怎么coding出快速排序法。至于什么复杂度之类的,请参考http://zh.wikipedia.org/wiki/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F#C.

  快速排序法的核心是分治法(Divide and conquer),也就是把一个数组一分为二,二分为四....直到不能分了,也就完成排序了。所以快速排序法也就是怎么分的问题。怎么分?当然是按大小分了。所以快速排序法的升序步骤描述为:

  1. 选择一个基准元素
  2. 交换数组元素。把小于基准值的放到左边;大于基准值放右边;等于的放任意一边。保证基准元素就是分割线的位置。
  3. 将基准值左、右边的元素作为子数组(都不包括基准元素),重复上面两个步骤直到数组元素数量小于2

现在得出C++下代码:

#include <iostream>

using namespace std;

#define MAX_ARRAY 10

/**
 * @brief divide 分割数组
 * @param list
 * @param length
 * @return 分割位置
 * 以数组第一个元素为基准分割数组,
 * 左边为小于基准,右边大于基准
 * 以移动分割线的方法实现分割
 */
int divide( int *list,int length )
{
    int divide_line = 0;  /* 默认分割线 */
    int pivot = list[0];  /* 默认选择第一个作为基准 */

    swap ( list[0],list[length-1] );    /* 把基准放到最后,这样最后一个永远不会被交换 */

    for ( int i = 0;i < length;i ++ )
    {
        if ( list[i] < pivot )  /* 小于基准,要放到分割线左边 */
        {
            swap( list[i],list[divide_line] );    /* 交换 */

            /* 小于基准的元素增长,分割线右移,保证分割线(包括分割线)右边都不小于基准 */
            divide_line ++;
        }
    }

    swap ( list[divide_line],list[length-1] ); /* 把最后一个交换到分割线,保证分割线值为基准值 */

    return divide_line;
}

/**
 * @brief conquer 排序子数组
 * @param list
 * @param length
 * 将数组进行分割,并对子数组进行排序
 */
void conquer( int *list,int length )
{
    if ( length <= 1 )  //已分解为一个元素不再分解
        return;

    int divide_line = divide( list,length );    /* 得到分割线 */

    conquer( list,divide_line );  //排序左边的数组
    conquer( list+divide_line+1,length - divide_line - 1 );  //排序右边的数组,基准值不再需要排序
}

/**
 * @brief quick_sort 快速排序法
 * @param list
 * @param length
 * 快速排序法
 */
void quick_sort( int *list,int length )
{
    conquer( list,length );
}

int main()
{
    int list[MAX_ARRAY] = { 9,0,1,3,5,8,4,6,2,7 };

    quick_sort( list,MAX_ARRAY );

    for ( int i = 0;i < MAX_ARRAY;i ++ )
    {
        cout << list[i] << " ";
    }

    cout << endl;

    return 0;
}

   当然,这只是一个原始的版本,旨在说明快速排序法的算法。当然还有更高级的版本,更优化的版本。一般情况下,我基本不会自己再去写一个快速排序法。现在C、C++的库都已包含大量排序算法。

  C里的快速排序法linux下man qsort即可看到用法及用例。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。