STL算法---排序算法(一)

来源:互联网 发布:鬼刀画册淘宝 编辑:程序博客网 时间:2024/06/05 19:52

1. nth_element

将范围内的序列重新排序, 使所有小于等于第n个元素的元素都出现在它前面,而大于它的都出现在后面。
重载版本使用自定义的比较操作
函数原形
template<class RanIt> void nth_element(RanIt first, RanIt nth, RanIt last);
template<class RanIt, class Pred> void nth_element(RanIt first, RanIt nth, RanIt last, Pred pr);
/////////////////////////////////////////////////////////////#include "stdafx.h"#include <algorithm>#include <numeric>#include <functional>#include <vector>#include <iostream>int _tmain(int argc, _TCHAR* argv[]){std::vector<int> nV2, nV1;std::vector<int>::iterator iter;nV1.clear();nV1.push_back(14);nV1.push_back(16);nV1.push_back(15);nV1.push_back(17);// --nV1.push_back(10);nV1.push_back(13);nV1.push_back(11);nV1.push_back(27);nV1.push_back(24);nV1.push_back(25);nV1.push_back(19);nV1.push_back(19);// 排序前: 14, 16, 15, 17, 10, 13, 11, 27, 24, 25, 19, 19std::nth_element(nV1.begin(), nV1.begin() + 3, nV1.end());// 排序后: 10, 11, 13, 14, 15, 16, 17, 19, 19, 24, 25, 27// 不是很明白!return 0;}
说明:
1. 不是很明白.
2. 网上有这个解析: 例如你需要得到排序后第4位的值, 那么就可以std::nth_element(nV1.begin(), nV1.begin() + 3, nV1.end()); 此时, 第4位肯定是正确的, 其他位不一定正确.
但我测试的都是全排列的.
3. MSDN的解析: 
"The nth_element algorithm does not guarantee that elements in the sub-ranges either side of the nth element are sorted. 
(nth_element算法不保证nth元素两边的子区间是排序的)
It thus makes fewer guarantees than partial_sort, which orders the elements in the range below some chosen element, and may be used as a faster alternative to partial_sort when the ordering of the lower range is not required.
(大概意思是, 如果你想更快速, 而不需要小于区间排序的话, 你可以使用nth_element算法来替换partial_sort算法.)
"

2. partial_sort / partial_sort_copy (部分排序)


2.1 partial_sort

对序列做部分排序, 被排序元素个数正好可以被放到范围内.
重载版本使用自定义的比较操作

函数原形

template<class RanIt> void partial_sort(RanIt first, RanIt middle, RanIt last);
template<class RanIt, class Pred> void partial_sort(RanIt first, RanIt middle, RanIt last, Pred pr);

2.2 partial_sort_copy

与partial_sort类似,不过将经过排序的序列复制到另一个容器
函数原形
template<class InIt, class RanIt> RanIt partial_sort_copy(InIt first1, InIt last1,RanIt first2, RanIt last2);
template<class InIt, class RanIt, class Pred> RanIt partial_sort_copy(InIt first1, InIt last1,RanIt first2, RanIt last2, Pred pr);

说明:
1. partial_sort中middle后面的数据可能是没有排序的, 如果middle等于last, 那就等于做的是全排列.
2. 同理partial_sort_copy, last2后面且last1前面的数据也是没有排序的.
3. 如果[first1, last1)和[first2, last2)的范围大小是一样的partial_sort_copy等于做的是全排列.
/////////////////////////////////////////////////////////////#include "stdafx.h"#include <algorithm>#include <numeric>#include <functional>#include <vector>#include <iostream>int _tmain(int argc, _TCHAR* argv[]){std::vector<int> nV2, nV1;std::vector<int>::iterator iter;nV1.clear();nV1.push_back(14);nV1.push_back(16);nV1.push_back(15);nV1.push_back(11);nV1.push_back(10);nV1.push_back(13);nV1.push_back(17);nV1.push_back(27);nV1.push_back(24);nV1.push_back(25);nV1.push_back(19);nV1.push_back(19);// 排序前: 14, 16, 15, 11, 10, 13, 17, 27, 24, 25, 19, 19std::partial_sort(nV1.begin(), nV1.begin() + 3, nV1.end());// 排序后: 10, 11, 13, 16(从这里开始没有排序), 15, 14, 17, 27, 24, 25, 19, 19nV1.clear();nV1.push_back(14);nV1.push_back(16);nV1.push_back(15);nV1.push_back(11);nV1.push_back(10);nV1.push_back(13);nV1.push_back(17);nV1.push_back(27);nV1.push_back(24);nV1.push_back(25);nV1.push_back(19);nV1.push_back(19);nV2.resize(nV1.size());// 排序前nV1: 14, 16, 15, 11, 10, 13, 17, 27, 24, 25, 19, 19iter = std::partial_sort_copy(nV1.begin(), nV1.end(), nV2.begin(), nV2.end());// 排序后nV2: 10, 11, 13, 14, 15, 16, 17, 19, 19, 24, 25, 27// 排序后nV1: 14, 16, 15, 11, 10, 13, 17, 27, 24, 25, 19, 19, end(iter)nV1.clear();nV1.push_back(14);nV1.push_back(16);nV1.push_back(15);nV1.push_back(11);nV1.push_back(10);nV1.push_back(13);nV1.push_back(17);nV1.push_back(27);nV1.push_back(24);nV1.push_back(25);nV1.push_back(19);nV1.push_back(19);nV2.resize(nV1.size());// 排序前nV1: 14, 16, 15, 11, 10, 13, 17, 27, 24, 25, 19, 19iter = std::partial_sort_copy(nV1.begin(), nV1.end(), nV2.begin(), nV2.end() - 2);// 排序后nV2: 10, 11, 13, 14, 15, 16, 17, 19, 19, 24, 0, 0// 排序后nV1: 14, 16, 15, 11, 10, 13, 17, 27, 24, 25(iter), 19, 19return 0;}

3. partition / stable_partition(分类排序)

在[first, last)内, 使用输入的函数,把结果为true的元素放在结果为false的元素之前

3.1 partition

函数原形
template<class BidIt, class Pred> BidIt partition(BidIt first, BidIt last, Pred pr);


3.2 stable_partition

与partition类似, 但了保留容器中的相对顺序
函数原形
template<class FwdIt, class Pred> FwdIt stable_partition(FwdIt first, FwdIt last, Pred pr);

说明:
1. 这里关键就是pr, 把结果为true的元素放在结果为false的元素之前.
2. pr操作符只有一个参数.
3. partition很适合对数据分类(分为两类, 因为只有true和false; 返回的BidIt就是分界线)
4. partition分成两类后, 左边/右边的元素与分类前的相对位置可能会变了.
5. stable_partition分成两类后, 左边/右边的元素与分类前的相对位置不变.
/////////////////////////////////////////////////////////////#include "stdafx.h"#include <algorithm>#include <numeric>#include <functional>#include <vector>#include <iostream>class MyObject1{  public:MyObject1(){}~MyObject1(){}// 括号操作符    bool operator()(int val1)      {          return (val1 <= 0);    }};int _tmain(int argc, _TCHAR* argv[]){std::vector<int> nV2, nV1;std::vector<int>::iterator iter;nV1.clear();nV1.push_back(14);nV1.push_back(16);nV1.push_back(15);nV1.push_back(11);nV1.push_back(10);nV1.push_back(13);nV1.push_back(17);nV1.push_back(27);nV1.push_back(24);nV1.push_back(25);nV1.push_back(19);nV1.push_back(19);// 排序前: 14, 16, 15, 11, 10, 13, 17, 27, 24, 25, 19, 19iter = std::partition(nV1.begin(), nV1.end(), MyObject1());// 排序后: 14(iter), 16, 15, 11, 10, 13, 17, 27, 24, 25, 19, 19nV1.clear();nV1.push_back(14);nV1.push_back(16);nV1.push_back(15);nV1.push_back(11);nV1.push_back(10);nV1.push_back(13);nV1.push_back(-2);nV1.push_back(27);nV1.push_back(24);nV1.push_back(-1);nV1.push_back(19);nV1.push_back(19);// 排序前: 14, 16, 15, 11, 10, 13, -2, 27, 24, -1, 19, 19iter = std::partition(nV1.begin(), nV1.end(), MyObject1());// 排序后: -1, -2, 15(iter), 11, 10, 13, 16, 27, 24, 14, 19, 19nV1.clear();nV1.push_back(14);nV1.push_back(16);nV1.push_back(15);nV1.push_back(11);nV1.push_back(10);nV1.push_back(13);nV1.push_back(-2);nV1.push_back(27);nV1.push_back(24);nV1.push_back(-1);nV1.push_back(19);nV1.push_back(19);// 排序前: 14, 16, 15, 11, 10, 13, -2, 27, 24, -1, 19, 19iter = std::stable_partition(nV1.begin(), nV1.end(), MyObject1());// 排序后: -2, -1, 14(iter), 16, 15, 11, 10, 13, 27, 24, 19, 19return 0;}

0 0
原创粉丝点击