快速排序算法之使用STL中partition和stable_partition

1.问题描述

使用STL中partition和stable_partition来编写快速排序。
注意:关于STL中partition和stable_partition可以参考这里

2.分析

  • 我们已经知道,partition和stable_partition是把一个容器按照第三个参数谓语分成两个部分。后者是稳定排序,不改变容器的相对位置,是一个稳定排序。
  • 那么,这两个函数已经把快速排序中分类这一步完成了,我们只需要进行递归这一部分了。

3.源码

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
template<typename T>
void printVec(T begin,T end)
{
    for(auto iter = begin;iter !=end;++iter)
        cout<<*iter<<" ";
    cout<<endl;
}
template<typename T>
void m_stableSort(T begin,T end)
{
    //递归的边界,如果只有一个元素就退出排序
    if(end - begin <= 1)
        return;
    auto sz = *begin;
    auto mid = std::stable_partition(begin,end,[sz](const int& value){ return value < sz;});

    if(mid > begin)
        m_stableSort(begin,mid);
    if(mid < end -1)
        m_stableSort(mid+1,end);
}


template<typename T>
void m_Sort(T begin,T end)
{
    //递归的边界,如果只有一个元素就退出排序
    if(end - begin <= 1)
        return;
    auto sz = *begin;

    auto mid = std::partition(begin,end,[sz](const int& value){ return value < sz;});

    //这里为什么需要交换mid和end-1这两个数?
    //如果序列是 1,2,3,那么partition之后还是1,2,3,就不需要交换
    //如果序列是 110,201,1,2,那么partition之后序列是,2,1,201,110,我们需要的中间值到尾部了,需要交换
    if(*mid != sz)
        std::swap(*mid,*(end-1));



    if(mid > begin)
        m_Sort(begin,mid);
    if(mid < end -1)
        m_Sort(mid+1,end);
}
int test08()
{
    std::vector<int> numbers{102,44,99,35,201,110,1,2};
    std::cout<<"print orige numbers:\n";
    printVec(numbers);
    std::cout<<std::endl;

    m_stableSort(numbers.begin(),numbers.end());

    std::cout<<"print after m_stableSort numbers:\n";
    printVec(numbers);
    std::cout<<std::endl;


    return 0;
}
int test09()
{
    std::vector<int> numbers{102,44,99,35,201,110,1,2};
    std::cout<<"print orige numbers:\n";
    printVec(numbers.begin(),numbers.end());

    m_Sort(numbers.begin(),numbers.end());

    std::cout<<"print after m_Sort numbers:\n";
    printVec(numbers.begin(),numbers.end());


    return 0;
}
int main()
{
    test08();
    test09();

    return 0;
}

运行结果图:
这里写图片描述

4.结论

我们发现如果我们使用partition算法,必须要对分成的两部分再进行处理。如果可以把swap这部分去掉,会得到意想不到的结果。所以,我们最好使用stable_partition算法,毕竟稳定,可以避免一些麻烦。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值