FP风格以及并发的快速排序

这是整理自C++并发编程实战4.12的代码
FP普通快排

/*
 * FP_sort.cpp
 *
 *  Created on: Nov 23, 2017
 *      Author: clh01s@163.com
 *      FP模式的快速排序以及使用future的并发快速排序
 */
#include <iostream>
#include <list>
#include <algorithm>    // std::partition
#include <utility>      // std::move

template<typename T>
std::list<T> sequential_quick_sort(std::list<T> input)
{
    if(input.empty())
    {
        return input;
    }

    std::list<T> result;
    //取出第一个元素作为中轴,方法是用splice将其从列表前段切下
    result.splice(result.begin(),input,input.begin());
    //为了以后比较考虑对他进行引用避免复制
    T const& pivot = *result.begin();

    /* 使用partition对列表中的元素重新排列
     * 在此例中满足 t < pivot 则放置在前段不满足则放置在后端
     *
     * 这里使用了一个lambda函数;并且使用引用捕获以避免复制pivot值
     */
    auto divide_point = std::partition(input.begin(),input.end(),
            [&](T const& t){return t < pivot;});

    /* 现在列表中的值已经被分为大于pivot的一半和小于pivot的一半
     * 如果打算递归排序这两半的列表则需要创建两个列表,所以这里
     * 使用了splice()将input到divide_point的值移动到新的表
     * 剩下的值就保存在input中
     */
    std::list<T> lower_part;
    lower_part.splice(lower_part.end(),input,input.begin(),
            divide_point);

    //使用srd::move()避免多余拷贝
    //递归调用进行排序
    auto new_lower(
            sequential_quick_sort(std::move(lower_part)));
    auto new_higher(
            sequential_quick_sort(std::move(input)));

    //最后使用splice将正确的值连起来,new_higher在后new_lower在前
    result.splice(result.end(),new_higher);
    result.splice(result.begin(),new_lower);

    return result;
}




int main()
{
    std::list<int> l;
    l.push_back(1);
    l.push_back(2);
    l.push_back(5);
    l.push_back(8);
    l.push_back(3);
    l.push_back(9);
    l.push_back(11);
    l.push_back(4);
    l.push_back(6);
    l.push_back(10);
    l.push_back(7);
    l.push_back(12);
    std::list<int> sort = sequential_quick_sort(l);
    for(auto it = sort.begin();it != sort.end();++it)
    {
        std::cout<<*it<<std::endl;
    }
    return 0;
}

程序输出:

clh@clh:~/testcode/并发$ g++ FP_sort.cpp -std=c++11
clh@clh:~/testcode/并发$ ./a.out 
1
2
3
4
5
6
7
8
9
10
11
12

并发:

//并发版本快排
/*
 * FP_sort.cpp
 *
 *  Created on: Nov 23, 2017
 *      Author: clh01s@163.com
 *      FP模式的快速排序以及使用future的并发快速排序
 */
#include <iostream>
#include <list>
#include <algorithm>    // std::partition
#include <utility>      // std::move
#include <future>

template<typename T>
std::list<T> parallel_quick_sort_future(std::list<T> input)
{
    if(input.empty())
    {
        return input;
    }

    std::list<T> result;
    //取出第一个元素作为中轴,方法是用splice将其从列表前段切下
    result.splice(result.begin(),input,input.begin());
    //为了以后比较考虑对他进行引用避免复制
    T const& pivot = *result.begin();

    /* 使用partition对列表中的元素重新排列
     * 在此例中满足 t < pivot 则放置在前段不满足则放置在后端
     *
     * 这里使用了一个lambda函数;并且使用引用捕获以避免复制pivot值
     */
    auto divide_point = std::partition(input.begin(),input.end(),
            [&](T const& t){return t < pivot;});

    /* 现在列表中的值已经被分为大于pivot的一半和小于pivot的一半
     * 如果打算递归排序这两半的列表则需要创建两个列表,所以这里
     * 使用了splice()将input到divide_point的值移动到新的表
     * 剩下的值就保存在input中
     */
    std::list<T> lower_part;
    lower_part.splice(lower_part.end(),input,input.begin(),
            divide_point);

    //在这里使用std::async()开启一个新的线程对较小的那一半进行排序
    //程序返回future类行,在其他操作处理之后在需要的时候调用future的get函数获取结果
    std::future<std::list<T>> new_lower(
            std::async(&parallel_quick_sort_future<T>,std::move(lower_part)));
    //在当前线程对较大的那一部分进行排序
    auto new_higher(
            sequential_quick_sort(std::move(input)));

    //最后使用splice将正确的值连起来,new_higher在后new_lower在前
    result.splice(result.end(),new_higher);
    //调用get函数获取结构然后进行拼接
    result.splice(result.begin(),new_lower.get());

    return result;
}

int main()
{
    std::list<int> l;
    l.push_back(1);
    l.push_back(2);
    l.push_back(5);
    l.push_back(8);
    l.push_back(3);
    l.push_back(9);
    l.push_back(11);
    l.push_back(4);
    l.push_back(6);
    l.push_back(10);
    l.push_back(7);
    l.push_back(12);
    std::list<int> sort = parallel_quick_sort_future(l);
    for(auto it = sort.begin();it != sort.end();++it)
    {
        std::cout<<*it<<std::endl;
    }
    return 0;
}

输出:

clh@clh:~/testcode/并发$ g++ FP_sort.cpp -std=c++11 -pthread
clh@clh:~/testcode/并发$ ./a.out 
1
2
3
4
5
6
7
8
9
10
11
12

转载请注明源地址:http://blog.youkuaiyun.com/clh01s/article/details/78631369

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值