排序算法这么多,为什么快速排序叫做快速排序算法呢?其实它也并没有那么快,它与其它算法区别呢?看上去一点体现不出它的分治特点,什么?不知道分治,那就简单看一下下面吧:
分治法的设计思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
一个分治法将规模为n的问题分成k个规模为n/m的子问题去解。设分解阀值n0=1,且adhoc解规模为1的问题耗费1个单位时间。再设将原问题分解为k个子问题以及用merge将k个子问题的解合并为原问题的解需用f(n)个单位时间。用T(n)表示该分治法解规模为|P|=n的问题所需的计算时间,则有:
T(n)= k T(n/m)+f(n)
小弟拙拙地介绍下快速排序吧,其实就是把一堆东西分成两份,一份小的,一份大的,小的比大那份都要小,取第一个作为中间量,把比他小的放左边,再把大的放右边,然后这两份又分别分成小的跟大的,不断地分直到不能再分。
我想用种比较迂回的方式探讨一下快速排序的时间复杂度,经典的逻辑问答游戏:1到100个炸弹,有一个是真的,你只能问是或否的问题,你要怎么问才能最快得出答案呢?你应该采取什么策略呢?很显然,二分。先是猜是不是位于1~50之间,排除掉一半可能性,然后对区间继续二分。这种策略能够保证无论数字怎么跟你捉迷藏,都能在log_2{n}次以内猜中。这种策略是平衡的,反之如果策略不是平衡的,比如问是不是在1~10之间,那么一旦发现不是在1~10之间的话就会剩下比N/2更多的可能性需要去考察了。
再比如常见的什么称重问题让你最少次数称出n个球中不同的那个,比如12个球,一个不同,最小化剩下三个球就能确定,天平的结果状态可能有三种,平衡,倾向左或右,那如果一开始66二分的话就只有两种可能性,第三种可能为零了,可能性不满足平衡,所以我们应当尽量让这三个分支概率均等,即平均切分所有的可能性为三等份。如此一来的话一次称量就可以将答案的可能性缩减为原来的1/3,三次就能缩减为1/27。而总共才有24种可能性,所以理论上是完全可以3次称出来的。4、4称了之后不管哪种情况,剩下来的可能性总是4种。这是一个完美的三分。
排序可以这样说:一组未排序的N个数字,它们一共有N!种重排,其中只有一种排列是满足题意的(譬如从小到大排列)。换句话说,排序问题的可能性一共有N!种。快速排序把整体分成两份,比如每次在比较a和b的时候,a<b和a>b的概率是均等的,通过比较方式来排只有两种可能性,这样我们就能保证无论如何都能将可能性缩小为原来的一半了!快速排序的复杂度就变成log_2{N!},即近似的nlogn。
快速排序: public class QuickSort {
public static int Partition(int a[],int p,int r){
int x=a[r-1];
int i=p-1;
int temp;
for(int j=p;j<=r-1;j++){
if(a[j-1]<=x){
// swap(a[j-1],a[i-1]);
i++;
temp=a[j-1];
a[j-1]=a[i-1];
a[i-1]=temp;
}
}
//swap(a[r-1,a[i+1-1]);
temp=a[r-1];
a[r-1]=a[i+1-1];
a[i+1-1]=temp;
return i+1;
}
public static void quickSort(int a[],int p,int r){
if(p<r){
int q=Partition(a,p,r);
quickSort(a,p,q-1);
quickSort(a,q+1,r);
}
}
public static void main(String[] stra){
int a[]={3,51,17,31,14,36,95,13,45,53};
quickSort(a,1,10);
for (int i=1;i<=10;i++)
System.out.println(a[i-1]);
}
}