快速排序:
百度百科:快速排序(Quicksort)是对冒泡排序的一种改进。
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
算法:用量个变量l,r 分别位于数组左右两端,一半以数组第一个元素为n中心元素
l,r向中间查找,r遇到比n小的数把他与n交换,l遇到比n大的元素把他与n交换
最后当l等于r,一遍排序完成
进行递归调用,把n左右两边的元素当成数组进行快速排序
时间复杂度:平均时间:O(nlog2n) 最坏时间: O(n^2)
附:常见的算法时间复杂度由小到大依次为:Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n2)<Ο(n3)<…<Ο(2n)<Ο(n!)
代码(升序):
#include<stdio.h> #define N 7 void quicksort(int a[],int l,int r); int main() { int a[N]={21,54,7,11,98,43,0}; int l=0; int r=N-1; int i; quicksort(a,l,r);//接受数组地址并排序 for(i=0;i<N;i++) printf("%d ",a[i]); return 0; } void quicksort(int a[],int l,int r) { int i,j,n;//设置2个变量,一个在左,一个在右 if(l<r)//当l和r重合时排序完成 { i=l; j=r; n=a[i]; //一第一个元素作为中间值,按照它的大小把数组分成左右两部分 while(i<j) //i j相等时一遍快速排序完成 { while(i<j&&a[j]>n)//开始时先从右向左,找到第一个比n小的元素 j--; if(i<j) a[i++]=a[j];//把第一个比n小的数与n交换,这里是赋值,其实效用是一样,看讲解 while(i<j&&a[i]<n)//再从左向右,找到第一个比n大的元素 i++; if(i<j) a[j--]=a[i];//把第一个比n大的数与n交换,同上 } a[i]=n;//由于是上面不是交换,而是赋值,最后填上那个重复的数 quicksort(a,l,i-1);//递归调用,把n右边的数组排序 quicksort(a,i+1,r);//递归调用,把n左边的数组排序 } }
快速排序利用的时递归调用,使用起来确实非常方便,刚开始接触这种排序,花了好几天的空闲时间.....开始搜了一下这种排序,
有很多种算法,上面的是较为简洁的一种。众多算法大同小异,实质都是把找到的比n小或大的数与n交换,以上面程序为例:
a[i++]=a[j];
a[j--]=a[i];
这两个看起来是赋值,而不是交换。这里可以这样理解:
把a[j]赋值给a[i],这时a[i]中是n,赋值以后,a[i]与a[j]中都是比n小的那个元素,i也变成i+1为下面的做准备;
现在a[j]中相当于那个n,但这个n还没有定型,因为这个n(现在是a[j])还需要与其他元素进行交换;
i向后寻找到一个比n大的元素,j的坐标没有改变,把他赋值给a[j],这时相当于a[j]本来是n,现在与a[i]交换,所以现在有两个a[i],相当于把n转移到了找到的那个a[i]中,然后继续j继续寻找比n小的元素赋值上个a[i]中.....一直进行,
n=a[i];
最后一步:i中的元素已经赋值给了另一个元素,然后i/j继续向中间寻找,i找到了j或j找到了i,这个a[i]就是n。把n赋值给a[i],结束。这种写法看起来简洁,也可以每次找到都把n与a[i]/a[j]交换,两者等效。
常见的算法时间复杂度由小到大依次为:Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n2)<Ο(n3)<…<Ο(2n)<Ο(n!)