虽然功能强大的STL里的sort函数就是快速排序的实现,而且,系统的快排速度和手写的快排速度差不多。但是,我觉得还是有必要学会手写快排,至少手写的快排比系统快排更灵活,起码不需要重定义大于运算符来实现数据的从大到小排序。
手写快排的实现:
一、总体思想:
快速排序,简称快排,总体上来说是运用分治思想实现有序排列数据的一种排序方法。一言以蔽之:选择一个点,大的往一侧去,小的往另一侧去。再以这个点为起点和重点对两侧的数据进行同类操作,当两个区间内元素为一时,整个数据就是有序的了。因为这种排序方法对于随机数据的平均性能最好,速度最快,因此称它为快速排序。(经测试,对于100个随机数据,sort平均可以在0.015s内完成排序)
二、代码实现:
这里以将数组a[i]从小到大排序为例:
int a[101];
void hand_write_quick_sort(int l,int r)
{
if(l>=r) return;
else
{
int i=l;
int j=r;
int top=a[i]; //a[i]即为我们选择的“点”,用于分割
//(我们用的是这个点的值,而不是位置。)
while(i<j)
{
while(top<=a[j] && (i<j)) j--;
//a[j]比top大,则换下一个进行比较
a[i]=a[j];//"点"的位置变为a[j]
while(a[i]<=top && (i<j)) i++;
//a[i]比top小,则换下一个进行比较
a[j]=a[i];//"点"的位置变为a[i]
} //小的往前去,大的往后退。
a[i]=top;
hand_write_quick_sort(l,i-1);
hand_write_quick_sort(i+1,r);
}
}
应该很好理解。
三、注意事项
- 首先,快排很快,平均性能最好,但不代表不消耗时间,各种数据,各种性能都很好,对于一些特殊数据,快排的效率不如另一些排序方法高,甚至会被一些数据卡掉(解决方法是随机找寻“点”),所以,合适最好。
- 就像我开头说的那样,STL库里的sort函数就是快排,而且时间效率也很高,和手写的基本没差。所以如果记不下代码的,会使用sort函数也可以代替,需要时修改一下比较方式也可以,但手写sort当然还是要更灵活一些。
四、STL库中的sort比较方式的更改
好吧,感觉没什么写的了,还不想 就这么结笔,于是,我决定大发慈悲的介绍下如何更改sort的比较方式。
这里介绍个最常用的吧:将sort排序方式变为从大到小排
int a[1000];
bool cmp(int x,int y)
{return x>y;}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1,cmp);
//因为数组下标是从一开始的,所以要加一
}
这样得到的a数组就是从大到小排序的
- 小结:sort函数的使用:
sort(数组名+开始排序的下标,数组名+开始排序的下标+排序的长度,排序方式)
其中,排序方式不写的话,自动按从小到大排序。
*注:对结构体排序,还需重载一下比较运算符,这里就不详细说明了,不知道的可以自行查阅,也可以看我的另一篇文章(嘻嘻,做广告)。
好了,关于快排就讲这么多吧,记住一条原则——小的去一侧,大的去另一侧。嗯。。。
——————end.