STL中next_permutation和sort()的底层实现

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,即取整个序列的首、尾、中央三个地方的元素,以其中值作为枢轴。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值