这是整理自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(¶llel_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