快速排序法是一种在现实中经常被采用的一种排序方式,这里面又涉及递归的思想,这里我们先回顾一下相关概念:
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下编译输出结果为: