快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。
详细思想为:
- 先从数组中取一个基准数,一般为数组的第一个元素。
- 以这个基准数进行分区,比它大的数放右边,比它小的数放左边。经过此过程,数组元素就被分成了左右两个区间了。
- 对这两个区间重复第二个步骤,直到各区间只有一个元素。
其实就是:
- 先整一个基准数,以它为基准,比它小的放左边,比它大的放右边。
- 对数组进行多遍的多轮扫描,每一轮先右后左,右:从右往左扫描,左:从左往右扫描。
- 从右往左扫描,是一直扫哦,直到找到比基准数小的数或者从右扫完整个数组都没找到为止。
- 从左往右扫描,也是一直扫,直到找到比基准数大的数或者从左扫完整个数组都没找到为止。
- 每一遍搞定后,对分好的左右区间进行多轮扫描。直到分到分到每个区间只剩一个元素为止,也就是左边界==右边界时。
C语言实现
//Hello, i'm 九院干干 #include<stdio.h> #include<stdlib.h> void quick_sort(int a[], int l, int r) { if(l<r) //l=r时,这遍就分好区间了 { /* x为基准数,l为左边界,r为有边界, 以基准数为基准,先右后左地对数组进行扫描。 */ int i = l, j = r; int x=a[l]; while(i<j) //先左后右,进行多轮扫描,直到左边界等于有边界,即分区到各个区间只剩一个元素。 { while(i<j && a[j]>=x) j--; //从右向左进行扫描,直到找到比基准数小的数 if(i<j) a[i++] = a[j]; //若这一轮在i==j之前找到,将找到的数赋给左边的数组元素,再i加1,i向右边推进。 while(i<j && a[i]<x) i++; //从左向右进行扫描,直到找到比基准数大的数 if(i<j) a[j--] = a[i]; //若这一轮在i==j之前找到,将找到的数赋给右边的数组元素,再j减1,j向左边推进。 } a[i] = x; //搞定第一次分的区间后 quick_sort(a,l,i-1); //再搞定第一次分的左区间 quick_sort(a,i+1,r); //搞定第一次分的右区间 ,这上下两处其实就是分治思想的递归使用。 } } void main() { int a[100], l, r; int i, n; printf("please input the number of needing to sort:"); scanf("%d", &n); printf(" please input the element of needing to sort:"); for(i=1;i<=n;i++) scanf("%d", &a[i]); l=1; //左边界为数组序号为1的元素 r=n; //右边界就是最大序列数 quick_sort(a, l, r); //快速排序 printf(" the sequence after sorted:"); for(i=1;i<=n;i++) printf("%d ",a[i]); printf(" "); system("pause"); }
运行结果
Python实现
# Hello ,i'm 九院干干 def Quick_Sort(arry,l,r): if l<r: i=l j=r x=arry[l] while i<j: while i<j and arry[j]>=x: j=j-1 if i<j: arry[i]=arry[j] i=i+1 while i<j and arry[i]<x: i=i+1 if i<j: arry[j]=arry[i] j=j-1 arry[i]=x Quick_Sort(arry,l,i-1) Quick_Sort(arry,i+1,r) if __name__ == '__main__': arry=list(eval(input("请输入要排序的序列:"))) l=0 r=len(arry)-1 print("输入的序列为:",arry) Quick_Sort(arry,l,r) print("排好序的序列为:",arry)
运行结果