1. 我们都知道STL中next_permutation(iterator_first,iterator_end)和prev_permutation(iterator_first,iterator_end)分别是对一个序列的升序全排列和降序全排列(其中相同元素是同一种情况),废话不多说,我们更关心它的底层实现,代码如下:
代码源自:https://www.cnblogs.com/luruiyuan/p/5914909.html
/*
*算法实现:STL中的next_permutation实现
*/
#include<cstdio>
#include<cstring>
void inline swap(char *s1,char *s2){
char t=*s1;
*s1=*s2;
*s2=t;
}
/**
*反转字符串函数,s,e分别执行字符串的开始和结尾,不能反转中文
**/
void reverse(char *s,char* e){
for(e--;s<e;s++,e--)swap(s,e);
}
bool next_permutation(char *start,char *end){
char *cur = end-1, *pre=cur-1;
while(cur>start && *pre>=*cur)cur--,pre--;
if(cur<=start)return false;
for(cur=end-1;*cur<=*pre;cur--);//找到逆序中大于*pre的元素的最小元素
swap(cur,pre);
reverse(pre+1,end);//将尾部的逆序变成正序
return true;
}
int main(){
char s1[]="01224",s2[]="8000";
reverse(s1,s1+strlen(s1));
printf("%s\n",s1);
int n=strlen(s2);
puts("下一个排列:");
int cnt=0;
do{
puts(s2);
cnt++;
}while(next_permutation(s2,s2+n));
printf("%d",cnt);
}
//prev_permutation(iterator_first,iterator_end)相类似
2. 对于sort(),贴一下大佬的分析:https://blog.csdn.net/vanturman/article/details/81706538
STL的sort()算法,数据量大时采用Quick Sort,分段递归排序。一旦分段后的数据量小于某个阈值,为避免Quick Sort的递归调用带来过大的额外开销,就改用Insertion Sort(插入排序)。如果递归层次过深,还会改用Heap Sort。
STL中的sort并非只是普通的快速排序,除了对普通的快速排序进行优化,它还结合了插入排序和堆排序。根据不同的数量级别以及不同情况,能自动选用合适的排序方法。当数据量较大时采用快速排序,分段递归。一旦分段后的数据量小于某个阀值,为避免递归调用带来过大的额外负荷,便会改用插入排序。而如果递归层次过深,有出现最坏情况的倾向,还会改用堆排序。
快速排序最关键的地方在于枢轴的选择,最坏的情况发生在分割时产生了一个空的区间,这样就完全没有达到分割的效果。STL采用的做法称为median-of-three,即取整个序列的首、尾、中央三个地方的元素,以其中值作为枢轴。