STL基础——sort函数

关于快速排序

快速排序想必大家都知道,快排应该是各种排序算法中最普遍的了,因为它好打并且效率也挺高,平均时间复杂度为 Θ ( n log ⁡ n ) \Theta(n\log_n) Θ(nlogn),这是基于比较的排序方法时间下限。

相信大多数情况下,大家是这么写快排的:

#include<bits/stdc++.h>
using namespace std;
int n,a[100001];

void qsort(int l,int r)
{
	int mid=a[(l+r)/2],i=l,j=r;
	do
	{
		while(a[i]<mid) i++;
		while(a[j]>mid) j--;
		if(i<=j)
		{
			swap(a[i],a[j]);
			i++;
			j--;
		}
	}while(i<=j);
	if(l<j) qsort(l,j);
	if(i<r) qsort(i,r);
}

int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	
	qsort(1,n);
	
	for(int i=1;i<=n;i++)
		printf("%d ",a[i]);
	
	return 0;
}

但是!快排有一个很大的缺点,易退化,出题人只要想卡以上这种快排,针对性造几组数据就可以了。
比如这道题,如果你提交以上代码,得到的结果肯定是 TLE \colorbox{black}{\color{white}{TLE}} TLE
为什么呢会超时呢?因为如果数据是单调递减序列,快速排序就会退化为 O ( n ) O(n) O(n)的冒泡排序
听不懂的可以看看这张图辅助理解(个人认为这张图直观且明了):
pic
所以归并是神!
当然,快速排序也是有优化的,比如说三路快速排序内省排序
懂了,所以怎么实现?
但这些都不重要,接下来就请出我们的主角——STL

STL探幽

什么是STL

从根本上说,STL是一些“容器”的集合,这些“容器”有list,vector,set,map等,STL也是算法和其他一些组件的集合。这里的“容器”和算法的集合指的是世界上很多聪明人很多年的杰作。STL的目的是标准化组件,这样就不用重新开发,可以使用现成的组件。STL是C++的一部分,因此不用安装额外的库文件。——百度百科

反正好用就对了

STL基础——sort

既然说STL中有许多好用的模板,那么肯定少不了sort,如果你用下面的代码提交上面的模板题,肯定能A

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;
    int a[n];
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    sort(a,a+n);
    for(int i=0;i<n;i++)
	{
		cout<<a[i]<<" ";
	}
	return 0;
} 

怎么样,是不是很神奇?一个sort函数就能帮你省略这么多代码,而且效率异常的高,为什么呢?
因为从 2000 年 6 月起,SGI C++ STL 的 stl_algo.h 中 sort() 函数的实现采用了内省排序算法。

内省排序(英语:Introsort 或 Introspective sort)是快速排序和 堆排序 的结合,由 David Musser 于 1997 年发明。内省排序其实是对快速排序的一种优化,保证了最差时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)
内省排序将快速排序的最大递归深度限制为 ,超过限制时就转换为堆排序。这样既保留了快速排序内存访问的局部性,又可以防止快速排序在某些情况下性能退化为 O ( n 2 ) O(n^2) O(n2)。——OI wiki

所以说,sort简单好用且高效!

sort的食用方法

sort虽然是神器,但也要学会用才能让它发挥威力。
我们来看看它的函数原型:
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

posted @ 2020-10-30 20:20  榴恋666  阅读(125)  评论(0编辑  收藏  举报