快速排序法是一种在现实中经常被采用的一种排序方式,这里面又涉及递归的思想,这里我们先回顾一下相关概念:

1)递归:

递归是一种编程策略(分而治之),也是它把一个大的问题分解成具有相同形式的简单问题。它是一种强有力的思想,一旧题解了它,那就可以解决许多看似复杂的问题。

2)快速排序法:

逻辑思路就是先取一个分界点,在分界点左边都比它小,在分界点右边都比它大,下一步再将左右两边子数组再用同样方式进一步分割排序。这正符合递归的特点,将大的数组分成小数组后,进一步分割,以此类推,形成递归过程。递归过程注意为自己找好出口,不然就陷入死循环的深渊。

代码示例:

/* quicksort.c --- 
 * 
 * Filename: quicksort.c
 * Description: 练习快速排序法(递归方式)
 * Author: magc
 * Maintainer: 
 * Created: 日  7月 29 06:43:09 2012 (+0800)
 * Version: 
 * Last-Updated: 日  7月 29 14:23:03 2012 (+0800)
 *           By: magc
 *     Update #: 132
 * URL: 
 * Keywords: 
 * Compatibility: 
 * 
 */

/* Commentary: 
 * 
 * 
 * 
 */

/* Change Log:
 * 
 * 
 */

/* Code: */
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>

#define TRUE 1    //注意此处不需要加引号的哦
    
void sort(int a[],int len);
int patition(int a[],int len);


int main(int argc, char * argv[])
{
    int s[] = { 23,39,13,9,4,29,93 };
    sort(s,7);
    int i;
    for (i = 0; i < 7; i++) {
        printf("s[%d]--%d\n",i,s[i]);
    }
}

/**************************************************************************
函数名称:递归实现快速排序(升序)
功能描述:排序过程的子过程就是将数组分割为两个子数组,左边都比分界点小,右边都比分界点大,进而再对两个子数组采取同样操作,进一步分割。
输入参数:
返   回:
**************************************************************************/
void sort(int a[],int len)
{
    int boundary = patition(a,len); //分割数组,返回分界点下标值
    if(boundary<2)return ; //递归结束调用的条件,递归时要为自己找个后路,即出口,不然陷入死循环深渊
    printf("boundary--%d\n",boundary);
    sort(a,boundary);//以分界点为界,将左边子数组进一步递归调用
    sort(a+boundary+1,len - boundary - 1);//将分界点右侧子数组递归调用排序。
}

/**************************************************************************
函数名称:分割数组
功能描述:先选一个数为分界点,分割成两个子数组,左边比分界点都小,右边比分界点都大
输入参数:
返   回:返回分界点下标值
**************************************************************************/
int patition(int a[],int len)
{
    int pviot,temp , rh,lh;
    rh = len-1;
    lh = 1;
    
    if(len<2)return ;
    pviot = a[0];
    while(TRUE)
        {
            while(rh>lh&&a[rh]>pviot)rh--; //右边rh向左移动,直到遇到比分界点小的数停止移动 
            while(rh>lh&&a[lh]<pviot)lh++;//左边lh向右移动,直到遇到比分界点大的数停止移动
            if(rh == lh) break;//只有两个两个数重合时,结束
            temp = a[rh]; //rh和lh不重合时,要交换两个数,继续移动,直到rh与lh交汇到同一点上
            a[rh] = a[lh];
            a[lh] = temp;
        }
    if(a[rh] >=  pviot)return 0;//若rh和lh交汇点值比分界点值大,则结束语分割过程
    a[0] = a[rh];//若rh和lh交汇点比分界点(a[0])小的话,则将这两个数交换,然后才结束分割过程。
    a[rh] = pviot;
    return rh;
}

/* quicksort.c ends here */

 

在GCC下编译输出结果为: