第23章 排序算法(包括merge等)


  第23章 排序算法


 Sorting: 
1 sort Sort elements in range (function template)
2 stable_sort Sort elements preserving order of equivalents (function template)
3 partial_sort Partially Sort elements in range (function template)
4 partial_sort_copy Copy and partially sort range (function template)
5 nth_element Sort element in range (function template)
  
 Binary search (operating on sorted ranges): 
6 lower_bound Return iterator to lower bound (function template)
7 upper_bound Return iterator to upper bound (function template)
8 equal_range Get subrange of equal elements (function template)
9 binary_search Test if value exists in sorted array (function template)
  
 Merge (operating on sorted ranges): 
10 merge Merge sorted ranges (function template)
11 inplace_merge Merge consecutive sorted ranges (function template)
12 includes Test whether sorted range includes another sorted range (function template)
13 set_union Union of two sorted ranges (function template)
14 set_intersection Intersection of two sorted ranges (function template)
15 set_difference Difference of two sorted ranges (function template)
16 set_symmetric_difference Symmetric difference of two sorted ranges (function template)
  
 Heap: 
17 push_heap Push element into heap range (function template)
18 pop_heap Pop element from heap range (function template)
19 make_heap Make heap from range (function template)
20 sort_heap Sort elements of heap (function template)
  
 Min/max: 
21 min Return the lesser of two arguments (function template)
22 max Return the greater of two arguments (function template)
23 min_element Return smallest element in range (function template)
24 max_element Return largest element in range (function template)
25 lexicographical_compare Lexicographical less-than comparison (function template)
26 next_permutation Transform range to next permutation (function template)
27 prev_permutation Transform range to previous permutation (function template)

/*

  第23章 排序算法
   23.1 元素入堆push_heap
   23.2 创建堆make_heap
   23.3 元素出堆pop_heap
   23.4 堆排序sort_heap
   23.5 是否为堆is_heap
   23.6 局部排序partial_sort
   23.7 局部排序复制partial_sort_copy
   23.8 排序sort
   23.9 归并merge
   23.10 内部归并inplace_merge
   23.11 稳定排序stable_sort
   23.12 是否排序is_sorted
   23.13 第n个元素nth_element
   23.14 下确界lower_bound
   23.15 上确界upper_bound
   23.16 等价区间equal_range
   23.17 折半搜索binary_search
   23.18 子集合includes
   23.19 集合求并set_union
   23.20 集合求交set_intersection
   23.21 集合求差set_difference
   23.22 集合求异set_symmetric_difference
   23.23 最小值min
   23.24 最大值max
   23.25 最小元素min_element
   23.26 最大元素max_element
   23.27 字典比较lexicographical_compare
   23.28 下一排列组合next_permutation
   23.29 上一排列组合prev_permutation
   23.30 本章小结



书里排得太乱,按这个顺序整理:

Sorting:
sort    Sort elements in range (function template)
stable_sort    Sort elements preserving order of equivalents (function template)
partial_sort    Partially Sort elements in range (function template)
partial_sort_copy    Copy and partially sort range (function template)
nth_element    Sort element in range (function template)

Binary search (operating on sorted ranges):
lower_bound    Return iterator to lower bound (function template)
upper_bound    Return iterator to upper bound (function template)
equal_range    Get subrange of equal elements (function template)
binary_search    Test if value exists in sorted array (function template)

Merge (operating on sorted ranges):
merge    Merge sorted ranges (function template)
inplace_merge    Merge consecutive sorted ranges (function template)
includes    Test whether sorted range includes another sorted range (function template)
set_union    Union of two sorted ranges (function template)
set_intersection    Intersection of two sorted ranges (function template)
set_difference    Difference of two sorted ranges (function template)
set_symmetric_difference    Symmetric difference of two sorted ranges (function template)

Heap:
push_heap    Push element into heap range (function template)
pop_heap    Pop element from heap range (function template)
make_heap    Make heap from range (function template)
sort_heap    Sort elements of heap (function template)

Min/max:
min    Return the lesser of two arguments (function template)
max    Return the greater of two arguments (function template)
min_element    Return smallest element in range (function template)
max_element    Return largest element in range (function template)

lexicographical_compare    Lexicographical less-than comparison (function template)

next_permutation    Transform range to next permutation (function template)
prev_permutation    Transform range to previous permutation (function template)



    Sorting:    
1    sort    Sort elements in range (function template)
2    stable_sort    Sort elements preserving order of equivalents (function template)
3    partial_sort    Partially Sort elements in range (function template)
4    partial_sort_copy    Copy and partially sort range (function template)
5    nth_element    Sort element in range (function template)
        
    Binary search (operating on sorted ranges):    
6    lower_bound    Return iterator to lower bound (function template)
7    upper_bound    Return iterator to upper bound (function template)
8    equal_range    Get subrange of equal elements (function template)
9    binary_search    Test if value exists in sorted array (function template)
        
    Merge (operating on sorted ranges):    
10    merge    Merge sorted ranges (function template)
11    inplace_merge    Merge consecutive sorted ranges (function template)
12    includes    Test whether sorted range includes another sorted range (function template)
13    set_union    Union of two sorted ranges (function template)
14    set_intersection    Intersection of two sorted ranges (function template)
15    set_difference    Difference of two sorted ranges (function template)
16    set_symmetric_difference    Symmetric difference of two sorted ranges (function template)
        
    Heap:    
17    push_heap    Push element into heap range (function template)
18    pop_heap    Pop element from heap range (function template)
19    make_heap    Make heap from range (function template)
20    sort_heap    Sort elements of heap (function template)
        
    Min/max:    
21    min    Return the lesser of two arguments (function template)
22    max    Return the greater of two arguments (function template)
23    min_element    Return smallest element in range (function template)
24    max_element    Return largest element in range (function template)
25    lexicographical_compare    Lexicographical less-than comparison (function template)
26    next_permutation    Transform range to next permutation (function template)
27    prev_permutation    Transform range to previous permutation (function template)



*/
View Code

  Sorting: 

/*****************************************************************************************************
Sorting:
sort    Sort elements in range (function template)
stable_sort    Sort elements preserving order of equivalents (function template)
partial_sort    Partially Sort elements in range (function template)
partial_sort_copy    Copy and partially sort range (function template)
nth_element    Sort element in range (function template)
*/


1 sort Sort elements in range (function template)

// sort  ----------------------------------------------------------------------------------------


template <class RandomAccessIterator>
  void sort ( RandomAccessIterator first, RandomAccessIterator last );

template <class RandomAccessIterator, class Compare>
  void sort ( RandomAccessIterator first, RandomAccessIterator last, Compare comp );

/*
Sort elements in range
Sorts the elements in the range [first,last) into ascending order.
The elements are compared using operator< for the first version, and comp for the second.
*/



// sort algorithm example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool myfunction (int i,int j) { return (i<j); }

struct myclass {
  bool operator() (int i,int j) { return (i<j);}
} myobject;

int main () {
  int myints[] = {32,71,12,45,26,80,53,33};
  vector<int> myvector (myints, myints+8);               // 32 71 12 45 26 80 53 33
  vector<int>::iterator it;

  // using default comparison (operator <):
  sort (myvector.begin(), myvector.begin()+4);           //(12 32 45 71)26 80 53 33

  // using function as comp
  sort (myvector.begin()+4, myvector.end(), myfunction); // 12 32 45 71(26 33 53 80)

  // using object as comp
  sort (myvector.begin(), myvector.end(), myobject);     //(12 26 32 33 45 53 71 80)

  // print out content:
  cout << "myvector contains:";
  for (it=myvector.begin(); it!=myvector.end(); ++it)
    cout << " " << *it;

  cout << endl;

  return 0;
}


// sort algorithm example. my test
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool myfunction (int i,int j) { return (j<i); } // i<j改为了j<i

struct myclass {
  bool operator() (int i,int j) { return (j<i);}  // i<j改为了j<i
} myobject;
// 注意调用顺序。i在左,j在右。其它元素,比如结构等,也可以自定义排序规则

void print( vector<int> &v )
{
  // print out content:
  cout << "myvector contains:";
  for ( vector<int>::iterator it=v.begin(); it!=v.end(); ++it)
    cout << " " << *it;
  cout << endl;  
}  

int main () {
  int myints[] = {32,71,12,45,26,80,53,33};
  vector<int> myvector (myints, myints+8);               // 32 71 12 45 26 80 53 33
  vector<int>::iterator it;

  // using default comparison (operator <):
  sort (myvector.begin(), myvector.begin()+4);           //(12 32 45 71)26 80 53 33
  print(myvector);
  
  // using function as comp
  sort (myvector.begin()+4, myvector.end(), myfunction); // 12 32 45 71(80 53 33 26)
  print(myvector);
  
  // using object as comp
  sort (myvector.begin(), myvector.end(), myobject);     //(12 26 32 33 45 53 71 80)倒过来
  print(myvector);

  return 0;
}


// 365
#include <algorithm>
#include <iostream>
#include <functional> // greater
using namespace std;
void print(int x)
{
  cout << x << ' ';
}
int main(void)
{
  int iArray[] = { 2, 8,  - 15, 90, 26, 7, 23, 30,  - 27, 39, 55 };
  const int len = sizeof(iArray) / sizeof(int);
  //
  cout << "由小到大排序" << endl;
  sort(iArray, iArray + len);
  for_each(iArray, iArray + len, print);
  cout << endl;
  //
  cout << "由大到小排序" << endl;
  sort(iArray, iArray + len, greater < int > ()); 
  // greater是标准库定义的函数对象。greater<int>是类型,greater<int>(),会产生一个函数对象

  for_each(iArray, iArray + len, print);
  cout << endl;
  return 0;
}


2 stable_sort Sort elements preserving order of equivalents (function template)

// stable_sort  ----------------------------------------------------------------------------------------


template <class RandomAccessIterator>
  void stable_sort ( RandomAccessIterator first, RandomAccessIterator last );

template <class RandomAccessIterator, class Compare>
  void stable_sort ( RandomAccessIterator first, RandomAccessIterator last,
                     Compare comp );

/*
Sort elements preserving order of equivalents

Sorts the elements in the range [first,last) into ascending order, like sort, but stable_sort grants that 
the relative order of the elements with equivalent values is preserved.

The elements are compared using operator< for the first version, and comp for the second.
*/



// stable_sort example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool compare_as_ints (double i,double j)
{
  return (int(i)<int(j));
}

int main () {
  double mydoubles[] = {3.14, 1.41, 2.72, 4.67, 1.73, 1.32, 1.62, 2.58};

  vector<double> myvector;
  vector<double>::iterator it;

  myvector.assign(mydoubles,mydoubles+8);

  cout << "using default comparison:";
  stable_sort (myvector.begin(), myvector.end());
  for (it=myvector.begin(); it!=myvector.end(); ++it)
    cout << " " << *it;

  myvector.assign(mydoubles,mydoubles+8);

  cout << "
using 'compare_as_ints' :";
  stable_sort (myvector.begin(), myvector.end(), compare_as_ints);
  for (it=myvector.begin(); it!=myvector.end(); ++it)
    cout << " " << *it;

  cout << endl;

  return 0;
}



// stable_sort example. my test:以下程序,在vc6中运行正常,在guide中就编译通不过。
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

// print container content:
template <class T> void PrintCont ( T& cont )
{
  for (T::iterator it=cont.begin(); it!=cont.end(); ++it)
    cout << " " << *it;
  cout << endl;
}

int main () {
  double mydoubles[] = {3.14, 1.41, 2.72, 4.67, 1.73, 1.32, 1.62, 2.58};

  vector<double> myvector;
  vector<double>::iterator it;

  myvector.assign(mydoubles,mydoubles+8);
  PrintCont( myvector );


  return 0;
}



// 382
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;

struct Student
{
  int id;
  char *name;
  int score;
  Student(int id_, char *name_, int score_)
  {
    id = id_;
    name = name_;
    score = score_;
  }
};
bool compByid(Student s1, Student s2)
{
  return s1.id < s2.id ? 1 : 0;
}

bool compByscore(Student s1, Student s2)
{
  return s1.score < s2.score ? 1 : 0;
}
void print(Student s)
{
  cout << s.id << ' ' << s.name << ' ' << s.score << endl;
}

int main(void)
{
  vector < Student > v;
  v.push_back(Student(5, "李强", 90));
  v.push_back(Student(9, "王文", 80));
  v.push_back(Student(8, "张天", 87));
  v.push_back(Student(6, "丁宏", 90));
  v.push_back(Student(7, "赵庆", 99));
  //
  cout << "按学号执行sort算法排序:
";
  sort(v.begin(), v.end(), compByid);
  for_each(v.begin(), v.end(), print);
  cout << endl;
  //
  cout << "按分数执行stable_sort算法排序:
";
  stable_sort(v.begin(), v.end(), compByscore);
  for_each(v.begin(), v.end(), print);
  cout << endl;
  return 0;
}


3 partial_sort Partially Sort elements in range (function template)

// partial_sort  ----------------------------------------------------------------------------------------


template <class RandomAccessIterator>
  void partial_sort ( RandomAccessIterator first, RandomAccessIterator middle,
                      RandomAccessIterator last );

template <class RandomAccessIterator, class Compare>
  void partial_sort ( RandomAccessIterator first, RandomAccessIterator middle,
                      RandomAccessIterator last, Compare comp );

/*
Partially Sort elements in range
Rearranges the elements in the range [first,last), in such a way that the subrange [first,middle) contains 
the smallest elements of the entire range sorted in ascending order, and the subrange [middle,end) contains
the remaining elements without any specific order.
The elements are compared using operator< for the first version, and comp for the second.
*/
// 相当有意思,只排序出前几个。比如 6 5 8 1 7 9 2,如果只取前2,那么 1 2 .....
// 三个参数,开始、中间、结束。第三个参数可无,如有,是函数(对象)


// partial_sort example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool myfunction (int i,int j) { return (i<j); }

int main () {
  int myints[] = {9,8,7,6,5,4,3,2,1};
  vector<int> myvector (myints, myints+9);
  vector<int>::iterator it;

  // using default comparison (operator <):
  partial_sort (myvector.begin(), myvector.begin()+5, myvector.end());

  // using function as comp
  partial_sort (myvector.begin(), myvector.begin()+5, myvector.end(),myfunction);

  // print out content:
  cout << "myvector contains:";
  for (it=myvector.begin(); it!=myvector.end(); ++it)
    cout << " " << *it;

  cout << endl;

  return 0;
}
 


//355
#include <algorithm>
#include <iostream>
using namespace std;
void print(int x)
{
  cout << x << ' ';
}
int main(void)
{
  int iArray[] = { 3, 9, 6, 8,  - 10, 7,  - 11, 19, 30, 12, 23 };
  const int len = sizeof(iArray) / sizeof(int);
  for_each(iArray, iArray + len, print);
  cout << endl;
  //局部排序
  int middle = 5;
  partial_sort(iArray, iArray + middle, iArray + len); //
  cout << "middle=" << middle << endl;
  for_each(iArray, iArray + len, print);
  cout << endl;
  //局部排序
  middle = 8;
  partial_sort(iArray, iArray + middle, iArray + len);
  cout << "middle=" << middle << endl;
  for_each(iArray, iArray + len, print);
  cout << endl;
  return 0;
}


4 partial_sort_copy Copy and partially sort range (function template)

// partial_sort_copy  ----------------------------------------------------------------------------------------


template <class InputIterator, class RandomAccessIterator>
  RandomAccessIterator
    partial_sort_copy ( InputIterator first,InputIterator last,
                        RandomAccessIterator result_first,
                        RandomAccessIterator result_last );

template <class InputIterator, class RandomAccessIterator, class Compare>
  RandomAccessIterator
    partial_sort_copy ( InputIterator first,InputIterator last,
                        RandomAccessIterator result_first,
                        RandomAccessIterator result_last, Compare comp );

// partial_sort 复制到另一容器的版本
// 前两个参数是源范围,接着两个参数是目的地范围。第五个参数可选,如有,是双参数谓词判断函数(对象)




// partial_sort_copy example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool myfunction (int i,int j) { return (i<j); }

int main () {
  int myints[] = {9,8,7,6,5,4,3,2,1};
  vector<int> myvector (5);
  vector<int>::iterator it;

  // using default comparison (operator <):
  partial_sort_copy (myints, myints+9, myvector.begin(), myvector.end());

  // using function as comp
  partial_sort_copy (myints, myints+9, myvector.begin(), myvector.end(), myfunction);

  // print out content:
  cout << "myvector contains:";
  for (it=myvector.begin(); it!=myvector.end(); ++it)
    cout << " " << *it;

  cout << endl;

  return 0;
}
 


//358
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
void print(int x)
{
  cout << x << ' ';
}
int main(void)
{
  int iArray[] = { 3, 9, 6, 2, 11, 23, 80, 27, 1, 62, 55 };
  const int len = sizeof(iArray) / sizeof(int);
  //
  vector < int > v1(6);
  partial_sort_copy(iArray, iArray + len, v1.begin(), v1.end());
  for_each(v1.begin(), v1.end(), print);
  cout << endl;
  //
  vector < int > v2(len);
  partial_sort_copy(iArray, iArray + len, v2.begin(), v2.end());
  for_each(v2.begin(), v2.end(), print);
  cout << endl;
  return 0;
}


5 nth_element Sort element in range (function template)

// nth_element  ----------------------------------------------------------------------------------------



template <class RandomAccessIterator>
  void nth_element ( RandomAccessIterator first, RandomAccessIterator nth,
                     RandomAccessIterator last );

template <class RandomAccessIterator, class Comapre>
  void nth_element ( RandomAccessIterator first, RandomAccessIterator nth,
                     RandomAccessIterator last, Compare comp );

/*
Sort element in range
Rearranges the elements in the range [first,last), in such a way that the element at 
the resulting nth position is the element that would be in that position in a sorted sequence, 
with all the elements preceding it being smaller and all the elements following it greater than it. 
Neither the elements preceding it nor the elements following it are granted to be ordered.
The elements are compared using operator< for the first version, and comp for the second.
*/



// the element at the resulting nth position
// nth_element example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool myfunction (int i,int j) { return (i<j); }

int main () {
  vector<int> myvector;
  vector<int>::iterator it;

  // set some values:
  for (int i=1; i<10; i++) myvector.push_back(i);   // 1 2 3 4 5 6 7 8 9

  random_shuffle (myvector.begin(), myvector.end());

  // using default comparison (operator <):
  nth_element (myvector.begin(), myvector.begin()+5, myvector.end());
  cout << *(myvector.begin()+5) << endl;

  // using function as comp
  nth_element (myvector.begin(), myvector.begin()+5, myvector.end(),myfunction);
  cout << *(myvector.begin()+5) << endl;  

  // print out content:
  cout << "myvector contains:";
  for (it=myvector.begin(); it!=myvector.end(); ++it)
    cout << " " << *it;

  cout << endl;

  return 0;
}
 


//386
#include <algorithm>
#include <iostream>
using namespace std;
void print(int x)
{
  cout << x << ',';
}
int main(void)
{
  int iArray[]={7, 8, 6, 2, 9, 5, 10, 3, 0, 1, 13, 11, 12};
  const int len = sizeof(iArray) / sizeof(int);
  //
  cout << "打印iArray数组元素
";
  for_each(iArray, iArray + len, print);
  cout << endl;
  //执行nth_element算法
  cout << "*nth设为第9个元素,打印iArray数组元素
";
  nth_element(iArray, iArray + 9, iArray + len);
  for_each(iArray, iArray + len, print);
  cout << endl;
  
  cout << *(iArray + 9) << endl; // 从第0个位置开始数起,第9个
  cout << iArray[9] << endl; // 即iArray[9]
  
  return 0;
}

 Binary search (operating on sorted ranges): 

/******************************************************************************************************
Binary search (operating on sorted ranges):
lower_bound    Return iterator to lower bound (function template)
upper_bound    Return iterator to upper bound (function template)
equal_range    Get subrange of equal elements (function template)
binary_search    Test if value exists in sorted array (function template)
*/


6 lower_bound Return iterator to lower bound (function template)

// lower_bound    Return iterator to lower bound (function template) ----------------------------------------------------


template <class ForwardIterator, class T>
  ForwardIterator lower_bound ( ForwardIterator first, ForwardIterator last, const T& value )
{
  ForwardIterator it;
  iterator_traits<ForwardIterator>::distance_type count, step;
  count = distance(first,last);
  while (count>0) // 不是线性搜索,一个个找过去。也是类似于二分搜索
  {
    it = first; step=count/2; advance (it,step);
    if (*it<value)                   // or: if (comp(*it,value)), for the comp version
      { first=++it; count-=step+1;  }
    else count=step;
  }
  return first;
}
 
// 在有序的区间范围内,查找首个大于等于(>=)某值的位置。第四个参数,谓词判断,可选。
// 比如在 1 2 5 6 7 中,查找3,将定位在5所在的位置。



// lower_bound/upper_bound example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
  int myints[] = {10,20,30,30,20,10,10,20};
  vector<int> v(myints,myints+8);           // 10 20 30 30 20 10 10 20
  vector<int>::iterator low,up;

  sort (v.begin(), v.end());                // 10 10 10 20 20 20 30 30

  low=lower_bound (v.begin(), v.end(), 20); //          ^
  up= upper_bound (v.begin(), v.end(), 20); //                   ^

  cout << "lower_bound at position " << int(low- v.begin()) << endl;
  cout << "upper_bound at position " << int(up - v.begin()) << endl;

  return 0;
}
 

// 388
#include <algorithm>
#include <iostream>
int main(void)
{
  using namespace std;
  int iArray[] = { 3, 6, 9, 13, 18, 20, 27 };
  const int len = sizeof(iArray) / sizeof(int);
  int *result = lower_bound(iArray, iArray + len, 16);
  cout << "数组iArray中不小于16的下确界元素为" <<  *result << endl;
  return 0;
}


7 upper_bound Return iterator to upper bound (function template)

// upper_bound    Return iterator to upper bound (function template) ----------------------------------------------------


template <class ForwardIterator, class T>
  ForwardIterator upper_bound ( ForwardIterator first, ForwardIterator last, const T& value )
{
  ForwardIterator it;
  iterator_traits<ForwardIterator>::distance_type count, step;
  count = distance(first,last);
  while (count>0)
  {
    it = first; step=count/2; advance (it,step);
    if (!(value<*it))                 // or: if (!comp(value,*it)), for the comp version
      { first=++it; count-=step+1;  }
    else count=step;
  }
  return first;
}
 
// 在有序的区间范围内,查找首个大于(>)某值的位置。第四个参数,谓词判断,可选。
// 比如在 1 2 3 3 5 6 7 中,查找3,将定位在5所在的位置。
// 如在 1 2 5 6 7 中,查找3,lower_bound/upper_bound 都将定位在5所在位置。


// lower_bound/upper_bound example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
  int myints[] = {10,20,30,30,20,10,10,20};
  vector<int> v(myints,myints+8);           // 10 20 30 30 20 10 10 20
  vector<int>::iterator low,up;

  sort (v.begin(), v.end());                // 10 10 10 20 20 20 30 30

  low=lower_bound (v.begin(), v.end(), 20); //          ^
  up= upper_bound (v.begin(), v.end(), 20); //                   ^

  cout << "lower_bound at position " << int(low- v.begin()) << endl;
  cout << "upper_bound at position " << int(up - v.begin()) << endl;

  return 0;
}
 

// 389
#include <algorithm>
#include <iostream>
int main(void)
{
  using namespace std;
  int iArray[] = { 3, 6, 9, 13, 18, 20, 27 };
  const int len = sizeof(iArray) / sizeof(int);
  int *result = upper_bound(iArray, iArray + len, 13);
  cout << "数组iArray中大于13的上确界元素为" <<  *result << endl;
  return 0;
}


8 equal_range Get subrange of equal elements (function template)

// equal_range    Get subrange of equal elements (function template) ----------------------------------------------------


template <class ForwardIterator, class T>
  pair<ForwardIterator,ForwardIterator>
    equal_range ( ForwardIterator first, ForwardIterator last, const T& value )
{
  ForwardIterator it = lower_bound (first,last,value);
  return make_pair ( it, upper_bound(it,last,value) );
}
// 用折半查找记录第一个和最后一个可以插入某值的元素位置。
// 返回pair,first与second分别是lower_bound与upper_bound的返回值。第四个参数是谓词判断,可选。 


// equal_range example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool mygreater (int i,int j) { return (i>j); }

int main () {
  int myints[] = {10,20,30,30,20,10,10,20};
  vector<int> v(myints,myints+8);                         // 10 20 30 30 20 10 10 20
  pair<vector<int>::iterator,vector<int>::iterator> bounds;

  // using default comparison:
  sort (v.begin(), v.end());                              // 10 10 10 20 20 20 30 30
  bounds=equal_range (v.begin(), v.end(), 20);            //          ^        ^
  
  cout << "bounds at positions " << int(bounds.first - v.begin());
  cout << " and " << int(bounds.second - v.begin()) << endl;  

  // using "mygreater" as comp:
  sort (v.begin(), v.end(), mygreater);                   // 30 30 20 20 20 10 10 10
  bounds=equal_range (v.begin(), v.end(), 20, mygreater); //       ^        ^

  cout << "bounds at positions " << int(bounds.first - v.begin());
  cout << " and " << int(bounds.second - v.begin()) << endl;

  return 0;
}
 

// 392
#include <algorithm>
#include <iostream>
using namespace std;
void print(int x)
{
  cout << x << ',';
}
int main(void)
{
  int iArray[] = { 3, 6, 9, 10, 10, 10, 13, 16, 17, 20 };
  const int len = sizeof(iArray) / sizeof(int);
  pair < int *, int * > range = equal_range(iArray, iArray + len, 10);
  cout << "第一个可以插入10的元素为" <<  *range.first << endl;
  cout << "最后一个可以插入10的元素为" <<  *range.second << endl;
  cout << "所有可以在前面插入10的元素为";
  for_each(range.first, range.second + 1, print); // 如range.second为last,则可在最后插入
  cout << endl;
  return 0;
}


9 binary_search Test if value exists in sorted array (function template)

// binary_search    Test if value exists in sorted array (function template) --------------------------------------


template <class ForwardIterator, class T>
  bool binary_search ( ForwardIterator first, ForwardIterator last, const T& value )
{
  first = lower_bound(first,last,value);
  return (first!=last && !(value<*first));
}
// 在有序的范围内用折半搜索某值。找到返回true,找不到返回false。第四个参数是谓词判断,可选。

 
// binary_search example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool myfunction (int i,int j) { return (i<j); }

int main () {
  int myints[] = {1,2,3,4,5,4,3,2,1};
  vector<int> v(myints,myints+9);                         // 1 2 3 4 5 4 3 2 1

  // using default comparison:
  sort (v.begin(), v.end());

  cout << "looking for a 3... ";
  if (binary_search (v.begin(), v.end(), 3))
    cout << "found!
"; else cout << "not found.
";

  // using myfunction as comp:
  sort (v.begin(), v.end(), myfunction);

  cout << "looking for a 6... ";
  if (binary_search (v.begin(), v.end(), 6, myfunction))
    cout << "found!
"; else cout << "not found.
";

  return 0;
}


 
// 393
#include <algorithm>
#include <iostream>
using namespace std;
int main(void)
{
  int iArray[] = { 2, 3, 9, 12, 13, 20, 23, 26 };
  const int len = sizeof(iArray) / sizeof(int);
  if(binary_search(iArray, iArray + len, 13))
    cout << "数组iArray包含元素13" << endl;
  else
    cout << "数组iArray不包含元素13" << endl;
  return 0;
}


 



 Merge (operating on sorted ranges): 

/**************************************************************************************************************
Merge (operating on sorted ranges):
merge    Merge sorted ranges (function template)
inplace_merge    Merge consecutive sorted ranges (function template)
includes    Test whether sorted range includes another sorted range (function template)
set_union    Union of two sorted ranges (function template)
set_intersection    Intersection of two sorted ranges (function template)
set_difference    Difference of two sorted ranges (function template)
set_symmetric_difference    Symmetric difference of two sorted ranges (function template)
*/


10 merge Merge sorted ranges (function template)

// merge    Merge sorted ranges (function template) -------------------------------------


template <class InputIterator1, class InputIterator2, class OutputIterator>
  OutputIterator merge ( InputIterator1 first1, InputIterator1 last1,
                         InputIterator2 first2, InputIterator2 last2,
                         OutputIterator result )
{
  while (true) {
    *result++ = (*first2<*first1)? *first2++ : *first1++; // 取小者,加入result
    if (first1==last1) return copy(first2,last2,result);  // 一个到头,把另一个的剩余部分copy过去
    if (first2==last2) return copy(first1,last1,result);  // copy会返回result,所以merge也返回result
  }
}
 


// merge algorithm example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
  int first[] = {5,10,15,20,25};
  int second[] = {50,40,30,20,10};
  vector<int> v(10);
  vector<int>::iterator it;

  sort (first,first+5);
  sort (second,second+5);
  merge (first,first+5,second,second+5,v.begin());

  cout << "The resulting vector contains:";
  for (it=v.begin(); it!=v.end(); ++it)
    cout << " " << *it;

  cout << endl;
  
  return 0;
}
 



// 368
#include <algorithm>
#include <iostream>
using namespace std;

void print(int x)
{
  cout << x << ' ';
}

int main(void)
{
  int iArray1[3] = { 20, 23, 38 };
  int iArray2[6] = { 2, 9, 13, 18, 26, 30 };
  //升序归并
  int result[9];
  merge(iArray1, iArray1 + 3, iArray2, iArray2 + 6, result);
  for_each(result, result + 9, print);
  cout << endl;
  //降序归并
  int iArray3[5] = { 30, 20, 17, 8, 6 };
  int iArray4[4] = { 10, 5, 2, 0 };
  merge(iArray3, iArray3 + 5, iArray4, iArray4 + 4, result, greater < int > ());
  for_each(result, result + 9, print);
  cout << endl;
  return 0;
}


11 inplace_merge Merge consecutive sorted ranges (function template)

// inplace_merge    Merge consecutive sorted ranges (function template) -------------------------------------

template <class BidirectionalIterator>
  void inplace_merge ( BidirectionalIterator first, BidirectionalIterator middle,
                       BidirectionalIterator last );

template <class BidirectionalIterator, class Compare>
  void inplace_merge ( BidirectionalIterator first, BidirectionalIterator middle,
                       BidirectionalIterator last, Compare comp ); 

/*
Merge consecutive sorted ranges
Merges two consecutive sorted ranges: [first,middle) and [middle,last), 
putting the result into the combined sorted range [first,last). 
*/
// 将同容器中的内部两个升降同向的子序列进行排序合并。
// 三个参数:开始、中间、结束位置。第四个参数可选,如有,是谓词判断函数(对象)。



// inplace_merge example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
  int first[] = {5,10,15,20,25};
  int second[] = {50,40,30,20,10};
  vector<int> v(10);
  vector<int>::iterator it;

  sort (first,first+5);
  sort (second,second+5);

  copy (first,first+5,v.begin());
  copy (second,second+5,v.begin()+5);

  inplace_merge (v.begin(),v.begin()+5,v.end());

  cout << "The resulting vector contains:";
  for (it=v.begin(); it!=v.end(); ++it)
    cout << " " << *it;

  cout << endl;
  
  return 0;
}
 

// 376
#include <algorithm>
#include <iostream>
using namespace std;
void print(int x)
{
  cout << x << ' ';
}
int main(void)
{
  int iArray1[] = { 2, 4, 6, 8, 10, 1, 3, 5, 7, 9, 11, 13 };
  const int len1 = sizeof(iArray1) / sizeof(int);
  //升序内部归并
  inplace_merge(iArray1, iArray1 + 5, iArray1 + len1);
  for_each(iArray1, iArray1 + len1, print);
  cout << endl;
  //降序内部归并
  int iArray2[] = { 100, 80, 60, 40, 20, 10, 90, 70, 50, 30 };
  const int len2 = sizeof(iArray2) / sizeof(int);
  inplace_merge(iArray2, iArray2 + 6, iArray2 + len2, greater < int > ());
  for_each(iArray2, iArray2 + len2, print);  // 可以有第四个参数
  cout << endl;
  return 0;
}


12 includes Test whether sorted range includes another sorted range (function template)

// includes    Test whether sorted range includes another sorted range (function template) ------------------------------


template <class InputIterator1, class InputIterator2>
  bool includes ( InputIterator1 first1, InputIterator1 last1,
                  InputIterator2 first2, InputIterator2 last2 )
{
  while (first1!=last1)
  {
    if (*first2<*first1) break;
    else if (*first1<*first2) ++first1;
    else { ++first1; ++first2; }
    if (first2==last2) return true;
  }
  return false;
}
// 检测一个有序区间是否包含另一个有序区间,相当于一个集合包含关系的判断。
// 参数为两对。后一对当成子区间。第五个参数可选,如有,是谓词判断函数(对象)。
// 注意,不必连续相等。如 1 2 3 4 包含 1 3


// includes algorithm example
#include <iostream>
#include <algorithm>
using namespace std;

bool myfunction (int i, int j) { return i<j; }

int main () {
  int container[] = {5,10,15,20,25,30,35,40,45,50};
  int continent[] = {40,30,20,10};

  sort (container,container+10);
  sort (continent,continent+4);

  // using default comparison:
  if ( includes(container,container+10,continent,continent+4) )
    cout << "container includes continent!" << endl;

  // using myfunction as comp:
  if ( includes(container,container+10,continent,continent+4, myfunction) )
    cout << "container includes continent!" << endl;

  return 0;
}
 
 
// 394
#include <algorithm>
#include <iostream>
int main(void)
{
  using namespace std;
  int A[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
  const int lenA = sizeof(A) / sizeof(int);
  int B[] = { 2, 4, 6, 8, 10 };
  const int lenB = sizeof(B) / sizeof(int);
  //
  if(includes(A, A + lenA, B, B + lenB))
    cout << "B是A的子集合" << endl;
  else
    cout << "B不是A的子集合" << endl;
  return 0;
}


13 set_union Union of two sorted ranges (function template)

// set_union    Union of two sorted ranges (function template) -------------------------------------


template <class InputIterator1, class InputIterator2, class OutputIterator>
  OutputIterator set_union ( InputIterator1 first1, InputIterator1 last1,
                             InputIterator2 first2, InputIterator2 last2,
                             OutputIterator result )
{
  while (true) //  在归并的同时,去除了重复元素
  {
    if (*first1<*first2) *result++ = *first1++;
    else if (*first2<*first1) *result++ = *first2++;
    else { *result++ = *first1++; first2++; }

    if (first1==last1) return copy(first2,last2,result);
    if (first2==last2) return copy(first1,last1,result);
  }
}
// 对两个有序区间的元素进行集合求并。根据集合的互异性,重复元素只能留下一个。
// 第一对参数是区间一、第二对参数是区间二。第五个参数是目标位置,第六个参数可选。
// 函数返回的位置,类似于last。


// set_union example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
  int first[] = {5,10,15,20,25};
  int second[] = {50,40,30,20,10};
  vector<int> v(10);                           // 0  0  0  0  0  0  0  0  0  0
  vector<int>::iterator it;

  sort (first,first+5);     //  5 10 15 20 25
  sort (second,second+5);   // 10 20 30 40 50

  it=set_union (first, first+5, second, second+5, v.begin());
                                               // 5 10 15 20 25 30 40 50  0  0

  cout << "union has " << int(it - v.begin()) << " elements.
";

  return 0;
}
 

// 396 。区间二中的重复元素被跳过,区间一中的重复元素被保持。。
#include <algorithm>
#include <iostream>
using namespace std;
void print(int x)
{
  cout << x << ' ';
}
int main(void)
{
  int A[6] =
  {
    3, 3, 6, 9, 10, 12
  };
  int B[3] =
  {
    3, 8, 11
  };
  //
  int C[8] =
  {
    0, 0, 0, 0, 0, 0, 0, 0
  };
  set_union(A, A + 6, B, B + 3, C);
  for_each(C, C + 8, print);
  cout << endl;
  return 0;
}


14 set_intersection Intersection of two sorted ranges (function template)

// set_intersection    Intersection of two sorted ranges (function template) -------------------------------------

template <class InputIterator1, class InputIterator2, class OutputIterator>
  OutputIterator set_intersection ( InputIterator1 first1, InputIterator1 last1,
                                    InputIterator2 first2, InputIterator2 last2,
                                    OutputIterator result )
{
  while (first1!=last1 && first2!=last2)
  {
    if (*first1<*first2) ++first1;
    else if (*first2<*first1) ++first2;
    else { *result++ = *first1++; first2++; }
  }
  return result;
}
 
// 归并的同时求交集。
// 第六个参数可无,如有,是谓词函数(对象)。


// set_intersection example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
  int first[] = {5,10,15,20,25};
  int second[] = {50,40,30,20,10};
  vector<int> v(10);                           // 0  0  0  0  0  0  0  0  0  0
  vector<int>::iterator it;

  sort (first,first+5);     //  5 10 15 20 25
  sort (second,second+5);   // 10 20 30 40 50

  it=set_intersection (first, first+5, second, second+5, v.begin());
                                               // 10 20 0  0  0  0  0  0  0  0

  cout << "intersection has " << int(it - v.begin()) << " elements.
";

  return 0;
}
 


// 397
#include <algorithm>
#include <iostream>
using namespace std;
void print(int x)
{
  cout << x << ' ';
}
int main(void)
{
  int A[10] = { 3, 6, 6, 9, 13, 17, 18, 20, 23, 25 };
  int B[7] = { - 2,  - 1, 6, 9, 18, 30, 32 };
  //
  int C[20] = { 0 };
  set_intersection(A, A + 10, B, B + 7, C);
  for_each(C, C + 20, print);
  cout << endl;
  return 0;
}


15 set_difference Difference of two sorted ranges (function template)

// set_difference    Difference of two sorted ranges (function template) -------------------------------------


template <class InputIterator1, class InputIterator2, class OutputIterator>
  OutputIterator set_difference ( InputIterator1 first1, InputIterator1 last1,
                                  InputIterator2 first2, InputIterator2 last2,
                                  OutputIterator result )
{
  while (first1!=last1 && first2!=last2)
  {
    if (*first1<*first2) *result++ = *first1++;
    else if (*first2<*first1) first2++;
    else { first1++; first2++; }

  }
  return copy(first1,last1,result);
}
// 求两个集合的差。相当于求属于区间一、而不属于区间二的元素。第六个参数可选。



// set_difference example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
  int first[] = {5,10,15,20,25};
  int second[] = {50,40,30,20,10};
  vector<int> v(10);                           // 0  0  0  0  0  0  0  0  0  0
  vector<int>::iterator it;

  sort (first,first+5);     //  5 10 15 20 25
  sort (second,second+5);   // 10 20 30 40 50

  it=set_difference (first, first+5, second, second+5, v.begin());
                                               // 5 15 25  0  0  0  0  0  0  0

  cout << "difference has " << int(it - v.begin()) << " elements.
";

  return 0;
}
 



// 399
#include <algorithm>
#include <iostream>
using namespace std;
void print(int x)
{
  cout << x << ' ';
}
int main(void)
{
  int A[12]={1, 2, 3, 3, 3, 4, 5, 6, 7, 8, 9, 10};
  int B[6]={2, 3, 4, 6, 8, 10};
  int C[6]={0, 0, 0, 0, 0, 0};
  set_difference(A, A + 12, B, B + 6, C);
  for_each(C, C + 6, print);
  cout << endl;
  return 0;
}


16 set_symmetric_difference Symmetric difference of two sorted ranges (function template)

// set_symmetric_difference    Symmetric difference of two sorted ranges (function template) ----------------------------


template <class InputIterator1, class InputIterator2, class OutputIterator>
  OutputIterator
    set_symmetric_difference ( InputIterator1 first1, InputIterator1 last1,
                               InputIterator2 first2, InputIterator2 last2,
                               OutputIterator result )
{
  while (true)
  {
    if (*first1<*first2) *result++ = *first1++;
    else if (*first2<*first1) *result++ = *first2++;
    else { first1++; first2++; }

    if (first1==last1) return copy(first2,last2,result);
    if (first2==last2) return copy(first1,last1,result);
  }
}
// 对两集合求异。相当于求交集的补。即把不同时属于两个集合的元素挑选出来。 
// 注意,是集合一对集合二进行求异操作,所以集合一中的重复元素仍会存在。(如以下第二个程序中,集合中的第二个6)



// set_symmetric_difference example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
  int first[] = {5,10,15,20,25};
  int second[] = {50,40,30,20,10};
  vector<int> v(10);                           // 0  0  0  0  0  0  0  0  0  0
  vector<int>::iterator it;

  sort (first,first+5);     //  5 10 15 20 25
  sort (second,second+5);   // 10 20 30 40 50

  it=set_symmetric_difference (first, first+5, second, second+5, v.begin());
                                               // 5 15 25 30 40 50  0  0  0  0

  cout << "symmetric difference has " << int(it - v.begin()) << " elements.
";

  return 0;
}
 


// 401 . 老问题还在,集合一中的重复元素,还在
#include <algorithm>
#include <iostream>
using namespace std;
void print(int x)
{
  cout << x << ' ';
}
int main(void)
{
  int A[9]={3, 6, 6, 9, 12, 13, 15, 18, 20};
  int B[5]={2, 6, 15, 20, 30};
  int C[8]={0, 0, 0, 0, 0, 0, 0, 0};
  set_symmetric_difference(A, A + 9, B, B + 5, C);
  for_each(C, C + 8, print);
  cout << endl;
  return 0;
}


  



 Heap: 

/***********************************************************************************************************
Heap:
push_heap    Push element into heap range (function template)
pop_heap    Pop element from heap range (function template)
make_heap    Make heap from range (function template)
sort_heap    Sort elements of heap (function template)
*/


17 push_heap Push element into heap range (function template)

// push_heap    Push element into heap range (function template) -----------------------------------------

template <class RandomAccessIterator>
  void push_heap ( RandomAccessIterator first, RandomAccessIterator last );

template <class RandomAccessIterator, class Compare>
  void push_heap ( RandomAccessIterator first, RandomAccessIterator last,
                   Compare comp );

*/
Push element into heap range
Given a heap range [first,last-1), this function extends the range considered a heap to [first,last) by 
placing the value in (last-1) into its corresponding location in it.
/*
// 把堆的范围,扩大了一个元素。这个元素加入堆之后,会向上调整。


// range heap example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
  int myints[] = {10,20,30,5,15};
  vector<int> v(myints,myints+5);
  vector<int>::iterator it;

  make_heap (v.begin(),v.end());
  cout << "initial max heap   : " << v.front() << endl;

  pop_heap (v.begin(),v.end());  // 默认是大根堆
  v.pop_back();
  cout << "max heap after pop : " << v.front() << endl;

  v.push_back(99); // 在容器v中加了一个元素。原来的元素是堆化的。
  push_heap (v.begin(),v.end());  // 重新堆化。并不是全部重新调整,只要把新加的一个,向上调整就可以了。
  cout << "max heap after push: " << v.front() << endl;

  sort_heap (v.begin(),v.end());

  cout << "final sorted range :";
  for (unsigned i=0; i<v.size(); i++) cout << " " << v[i];

  cout << endl;

  return 0;
}
 

// 343
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
void print(int x)
{
  cout << x << ' ';
}
int main(void)
{
  vector < int > v;
  v.push_back(38);
  v.push_back(29);
  v.push_back(32);
  v.push_back(17);
  v.push_back(26);
  v.push_back(15);
  v.push_back(11);
  v.push_back(9);
  v.push_back(10);
  v.push_back(60); //入堆元素
  //将最后的元素60入堆
  push_heap(v.begin(), v.end()); // 因为是大根堆。60加入之后,向上调整,到了根节点上
  for_each(v.begin(), v.end(), print);
  cout << endl;
  return 0;
}


18 pop_heap Pop element from heap range (function template)

// pop_heap    Pop element from heap range (function template) --------------------------------------------------

template <class RandomAccessIterator>
  void pop_heap ( RandomAccessIterator first, RandomAccessIterator last );

template <class RandomAccessIterator, class Compare>
  void pop_heap ( RandomAccessIterator first, RandomAccessIterator last,
                   Compare comp );
/*
Pop element from heap range
Rearranges the elements in the range [first,last) in such a way that the part considered a heap is shortened 
by one by removing its highest element.
*/
// 实际上并非删除,而是交换。根节点元素与最后的元素交换,然后,堆的范围少了一,而新的根节点向下调整,形成新堆。


// range heap example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
  int myints[] = {10,20,30,5,15};
  vector<int> v(myints,myints+5);
  vector<int>::iterator it;

  make_heap (v.begin(),v.end());
  cout << "initial max heap   : " << v.front() << endl;

  pop_heap (v.begin(),v.end()); // 根节点上的30,跑到最后
  v.pop_back(); // 这下真的被删除了。 新堆中最大的是20
  cout << "max heap after pop : " << v.front() << endl;

  v.push_back(99); 
  push_heap (v.begin(),v.end());
  cout << "max heap after push: " << v.front() << endl;

  sort_heap (v.begin(),v.end());

  cout << "final sorted range :";
  for (unsigned i=0; i<v.size(); i++) cout << " " << v[i];

  cout << endl;

  return 0;
}
 


// 350
#include <algorithm>
#include <iostream>
using namespace std;
void print(int x)
{
  cout << x << ' ';
}
int main(void)
{
  int iArray[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
  const int len = sizeof(iArray) / sizeof(int);
  //
  cout << "创建堆" << endl;
  make_heap(iArray, iArray + len);
  for_each(iArray, iArray + len, print);
  cout << endl;
  //
  cout << "执行一次元素出堆" << endl;
  pop_heap(iArray, iArray + len); // 最大的9,跑最后面去了
  for_each(iArray, iArray + len, print);
  cout << endl;
  return 0;
}


19 make_heap Make heap from range (function template)

// make_heap    Make heap from range (function template) --------------------------------------------------

template <class RandomAccessIterator>
  void make_heap ( RandomAccessIterator first, RandomAccessIterator last );

template <class RandomAccessIterator, class Compare>
  void make_heap ( RandomAccessIterator first, RandomAccessIterator last,
                   Compare comp );

/*
Make heap from range
Rearranges the elements in the range [first,last) in such a way that they form a heap.
*/
// 重新排列元素顺序,使它们逻辑上构成一个堆。或者说堆化。


// range heap example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
  int myints[] = {10,20,30,5,15};
  vector<int> v(myints,myints+5);
  vector<int>::iterator it;

  make_heap (v.begin(),v.end()); // 堆化。默认成最大堆
  cout << "initial max heap   : " << v.front() << endl;

  for (unsigned i=0; i<v.size(); i++) cout << " " << v[i];
  cout << endl; // 一排数据是看不出来的。画成二叉树,就容易看出来

  return 0;
}



// 347
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
void print(int x)
{
  cout << x << ' ';
}
int main(void)
{
  vector < int > v;
  v.push_back(5);
  v.push_back(6);
  v.push_back(4);
  v.push_back(8);
  v.push_back(2);
  v.push_back(3);
  v.push_back(7);
  v.push_back(1);
  v.push_back(9);
  for_each(v.begin(), v.end(), print);
  cout << endl;
  //
  cout << "创建堆" << endl;
  make_heap(v.begin(), v.end());
  for_each(v.begin(), v.end(), print);
  cout << endl;
  return 0;
}


20 sort_heap Sort elements of heap (function template)

// sort_heap    Sort elements of heap (function template) --------------------------------------------------

template <class RandomAccessIterator>
  void sort_heap ( RandomAccessIterator first, RandomAccessIterator last );

template <class RandomAccessIterator, class Compare>
  void sort_heap ( RandomAccessIterator first, RandomAccessIterator last,
                   Compare comp );

/*
Sort elements of heap
Rearranges the elements in the heap range [first,last) in such a way that they form a sorted range. 
The comparisons are perfomed using operator< for the first version, and comp for the second.
*/
// 堆排序。默认是升序。(默认是大根堆)
// 注意,堆排序一句是一够的,排序前要建立好堆。



// range heap example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
  int myints[] = {10,20,30,5,15};
  vector<int> v(myints,myints+5);
  vector<int>::iterator it;

  make_heap (v.begin(),v.end());
  cout << "initial max heap   : " << v.front() << endl;

  for( int i=0; i<5; ++i ) // my test:不断把根节点往后交换,堆的大小一次比一次小。
    pop_heap (v.begin(),v.end()-i); // 最后容器中的元素,就从小到大排列了。

  cout << "final sorted range :";
  for (unsigned i=0; i<v.size(); i++) cout << " " << v[i];

  cout << endl;

  return 0;
}
 

// 352
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
void print(int x)
{
  cout << x << ' ';
}
int main(void)
{
  vector < int > v;
  v.push_back(3);
  v.push_back(9);
  v.push_back(6);
  v.push_back(3);
  v.push_back(12);
  v.push_back(17);
  v.push_back(20);
  for_each(v.begin(), v.end(), print);
  cout << endl;
  //建立堆
  make_heap(v.begin(), v.end()); // 堆排序前,要建立堆,否则失灵。
  //堆排序
  cout << "进行堆排序" << endl;
  sort_heap(v.begin(), v.end());
  for_each(v.begin(), v.end(), print);
  cout << endl;
  return 0;
}


  



 Min/max: 

/***********************************************************************************************************
Min/max: 本来分成三组,整一起了。
min    Return the lesser of two arguments (function template)
max    Return the greater of two arguments (function template)
min_element    Return smallest element in range (function template)
max_element    Return largest element in range (function template)
lexicographical_compare    Lexicographical less-than comparison (function template)
next_permutation    Transform range to next permutation (function template)
prev_permutation    Transform range to previous permutation (function template)
*/


21 min Return the lesser of two arguments (function template)

// min    Return the lesser of two arguments (function template) ------------------------------------

template <class T> const T& min ( const T& a, const T& b );
template <class T, class Compare>
  const T& min ( const T& a, const T& b, Compare comp );

template <class T> const T& min ( const T& a, const T& b ) {
  return (a<b)?a:b;     // or: return comp(a,b)?a:b; for the comp version
}
 
// 取小者。还可以加第三个参数。


// min example
#include <iostream>
#include <algorithm>
using namespace std;

int main () {
  cout << "min(1,2)==" << min(1,2) << endl;
  cout << "min(2,1)==" << min(2,1) << endl;
  cout << "min('a','z')==" << min('a','z') << endl;
  cout << "min(3.14,2.72)==" << min(3.14,2.72) << endl;
  return 0;
}
 

// 402
#include <algorithm>
#include <iostream>
bool strComp(const char *s1, const char *s2)
{
  return strcmp(s1, s2) < 0 ? 1 : 0;
}
int main(void)
{
  using namespace std;
  cout << min((char*)"green", (char*)"girl", strComp) << endl;
  cout << min(100, 30) << endl;
  return 0;
}


// my test. 尽量用Cpp的string
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

bool strComp(const string &s1, const string &s2)
{
  return s1<s2;
}

int main()
{
  cout << min( string("green"), string("girl"), strComp) << endl;
  cout << min(100, 30) << endl;
  return 0;
}


22 max Return the greater of two arguments (function template)

// max    Return the greater of two arguments (function template) ------------------------------------


template <class T> const T& max ( const T& a, const T& b ) {
  return (b<a)?a:b;     // or: return comp(b,a)?a:b; for the comp version
}
// 取大者。


// max example
#include <iostream>
#include <algorithm>
using namespace std;

int main () {
  cout << "max(1,2)==" << max(1,2) << endl;
  cout << "max(2,1)==" << max(2,1) << endl;
  cout << "max('a','z')==" << max('a','z') << endl;
  cout << "max(3.14,2.72)==" << max(3.14,2.72) << endl;
  return 0;
}
 


// 403
#include <algorithm>
#include <iostream>
int main(void)
{
  using namespace std;
  cout << max(100, 30) << endl;
  return 0;
}


23 min_element Return smallest element in range (function template)

// min_element    Return smallest element in range (function template) ------------------------------------


template <class ForwardIterator>
  ForwardIterator min_element ( ForwardIterator first, ForwardIterator last )
{
  ForwardIterator lowest = first; // 最小元素一定存在,不会跑到last上去
  if (first==last) return last;
  while (++first!=last)
    if (*first<*lowest)    // or: if (comp(*first,*lowest)) for the comp version
      lowest=first; // it停留在第一个最小值位置
  return lowest;
}
// 取得序列中第一个最小值的位置。



// min_element/max_element
#include <iostream>
#include <algorithm>
using namespace std;

bool myfn(int i, int j) { return i<j; }

struct myclass {
  bool operator() (int i,int j) { return i<j; }
} myobj;

int main () {
  int myints[] = {3,7,2,5,6,4,9};

  // using default comparison:
  cout << "The smallest element is " << *min_element(myints,myints+7) << endl;
  cout << "The largest element is " << *max_element(myints,myints+7) << endl;

  // using function myfn as comp:
  cout << "The smallest element is " << *min_element(myints,myints+7,myfn) << endl;
  cout << "The largest element is " << *max_element(myints,myints+7,myfn) << endl;

  // using object myobj as comp:
  cout << "The smallest element is " << *min_element(myints,myints+7,myobj) << endl;
  cout << "The largest element is " << *max_element(myints,myints+7,myobj) << endl;

  return 0;
}
 

// 405
#include <algorithm>
#include <list>
#include <iostream>
int main(void)
{
  using namespace std;
  list < int > l;
  l.push_back(13);
  l.push_back(6);
  l.push_back(9);
  l.push_back(3);
  l.push_back(20);
  //
  cout << "链表l的最小元素为" <<  *min_element(l.begin(), l.end()) << endl;
  return 0;
}


24 max_element Return largest element in range (function template)

// max_element    Return largest element in range (function template) ------------------------------------

template <class ForwardIterator>
  ForwardIterator max_element ( ForwardIterator first, ForwardIterator last )
{
  ForwardIterator largest = first;
  if (first==last) return last;
  while (++first!=last)
    if (*largest<*first)    // or: if (comp(*largest,*lowest)) for the comp version
      largest=first;
  return largest;
}
// 在序列中,取得最大值所在位置。可以有第三个参数。 


// min_element/max_element
#include <iostream>
#include <algorithm>
using namespace std;

bool myfn(int i, int j) { return i<j; }

struct myclass {
  bool operator() (int i,int j) { return i<j; }
} myobj;

int main () {
  int myints[] = {3,7,2,5,6,4,9};

  // using default comparison:
  cout << "The smallest element is " << *min_element(myints,myints+7) << endl;
  cout << "The largest element is " << *max_element(myints,myints+7) << endl;

  // using function myfn as comp:
  cout << "The smallest element is " << *min_element(myints,myints+7,myfn) << endl;
  cout << "The largest element is " << *max_element(myints,myints+7,myfn) << endl;

  // using object myobj as comp:
  cout << "The smallest element is " << *min_element(myints,myints+7,myobj) << endl;
  cout << "The largest element is " << *max_element(myints,myints+7,myobj) << endl;

  return 0;
}
 


// 405
#include <algorithm>
#include <vector>
#include <iostream>
int main(void)
{
  using namespace std;
  vector < int > v;
  v.push_back(30);
  v.push_back(25);
  v.push_back(32);
  v.push_back(23);
  v.push_back(38);
  v.push_back(21);
  //
  cout << "向量容器v的最大元素为" <<  *max_element(v.begin(), v.end()) << endl;
  return 0;
}


25 lexicographical_compare Lexicographical less-than comparison (function template)

// lexicographical_compare    Lexicographical less-than comparison (function template) ------------------------------------


template <class InputIterator1, class InputIterator2>
  bool lexicographical_compare ( InputIterator1 first1, InputIterator1 last1,
                                 InputIterator2 first2, InputIterator2 last2 )
{
  while (first1!=last1)
  {
    if (*first2<*first1 || first2==last2) return false
    else if (*first1<*first2) return true;
    first1++; first2++;
  }
  return true;
}
// 按字典方式给出两个区间序列的大小比较。第一区间较小时,返回true。
// 相等时,返回false。 见以下第二个程序,my test


// lexicographical_compare example
#include <iostream>
#include <algorithm>
#include <cctype>
using namespace std;

// a case-insensitive comparison function:
bool mycomp (char c1, char c2)
{ return tolower(c1)<tolower(c2); }

int main () {
  char first[]="Apple";         // 5 letters
  char second[]="apartment";    // 9 letters

  cout << "Using default comparison (operator<): ";
  if (lexicographical_compare(first,first+5,second,second+9))
    cout << first << " is less than " << second << endl;
  else
    if (lexicographical_compare(second,second+9,first,first+5))
      cout << first << " is greater than " << second << endl;
  else
    cout << first << " and " << second << " are equivalent
";


  cout << "Using mycomp as comparison object: ";
  if (lexicographical_compare(first,first+5,second,second+9,mycomp))
    cout << first << " is less than " << second << endl;
  else
    if (lexicographical_compare(second,second+9,first,first+5,mycomp))
      cout << first << " is greater than " << second << endl;
  else
    cout << first << " and " << second << " are equivalent
";

  return 0;
}


// my test
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

int main () {
  string sa("abc"),sb("abc");
  bool b=lexicographical_compare(sa.begin(),sa.begin()+sa.size(),
                                 sb.begin(),sb.begin()+sb.size());
  if(b) cout << "yes" << endl;
    else cout << "no" << endl;  // 相等时,返回false

  return 0;
}



// 406
#include <algorithm>
#include <iostream>
int main(void)
{
  using namespace std;
  char *s1 = "book";
  const int len1 = sizeof("book") / sizeof(char);
  char *s2 = "house";
  const int len2 = sizeof("house") / sizeof(char);
  bool result = lexicographical_compare(s1, s1 + len1, s2, s2 + len2);
  if(result)
    cout << "单词"book"在"house"前面" << endl;
  else
    cout << "单词"book"在"house"后面" << endl;
  return 0;
}


26 next_permutation Transform range to next permutation (function template)

// next_permutation    Transform range to next permutation (function template) ------------------------------------

template <class BidirectionalIterator>
  bool next_permutation (BidirectionalIterator first,
                         BidirectionalIterator last );

template <class BidirectionalIterator, class Compare>
  bool next_permutation (BidirectionalIterator first,
                         BidirectionalIterator last, Compare comp);


// 对区间元素进行一次组合排列,使之字典顺序大于原来的排列。如果做不到(排到最后了),返回false。



// next_permutation
#include <iostream>
#include <algorithm>
using namespace std;

int main () {
  int myints[] = {1,2,3};

  cout << "The 3! possible permutations with 3 elements:
";

  sort (myints,myints+3);

  do {
    cout << myints[0] << " " << myints[1] << " " << myints[2] << endl;
  } while ( next_permutation (myints,myints+3) );

  return 0;
}
 



// 408
#include <algorithm>
#include <iostream>
using namespace std;
void print(int x)
{
  cout << x << ' ';
}
template <class BidirectionalIter> void nextPermu_sort
  (BidirectionalIter first,BidirectionalIter last)
{
    while(next_permutation(first, last)){}
    //利用较大的组合返回true
}
int main(void)
{
  int iArray[] = { 3, 6, 2, 9, 8 };
  const int len = sizeof(iArray) / sizeof(int);
  cout << "原组合" << endl;
  for_each(iArray, iArray + len, print);
  cout << endl;
  cout << "新组合" << endl;
  next_permutation(iArray, iArray + len);
  for_each(iArray, iArray + len, print);
  cout << endl;
  //
  cout << "利用较慢的next_permutation算法排序
";
  nextPermu_sort(iArray, iArray + len);
  for_each(iArray, iArray + len, print);
  cout << endl;
  return 0;
}


27 prev_permutation Transform range to previous permutation (function template)

// prev_permutation    Transform range to previous permutation (function template) ------------------------------------

template <class BidirectionalIterator>
  bool prev_permutation (BidirectionalIterator first,
                         BidirectionalIterator last );

template <class BidirectionalIterator, class Compare>
  bool prev_permutation (BidirectionalIterator first,
                         BidirectionalIterator last, Compare comp);

// next_permutation是从前到后。这里的prev_permutation是从后到前。



// prev_permutation
#include <iostream>
#include <algorithm>
using namespace std;

int main () {
  int myints[] = {1,2,3};

  cout << "The 3! possible permutations with 3 elements:
";

  sort (myints,myints+3);
  reverse (myints,myints+3);

  do {
    cout << myints[0] << " " << myints[1] << " " << myints[2] << endl;
  } while ( prev_permutation (myints,myints+3) );

  return 0;
}
 


// 411

#include <algorithm>
#include <iostream>
using namespace std;
void print(int x)
{
  cout << x << ' ';
}
template <class BidirectionalIter> void prevPermu_sort
  (BidirectionalIter first, BidirectionalIter last)
{
    while(prev_permutation(first, last)){}
    //利用较小的组合返回true
}
int main(void)
{
  int iArray[] = { 1, 3, 9, 6, 7 };
  const int len = sizeof(iArray) / sizeof(int);
  cout << "原组合" << endl;
  for_each(iArray, iArray + len, print);
  cout << endl;
  cout << "新组合" << endl;
  prev_permutation(iArray, iArray + len);
  for_each(iArray, iArray + len, print);
  cout << endl;
  //
  cout << "利用较慢的prev_permutation算法排序
";
  prevPermu_sort(iArray, iArray + len);
  for_each(iArray, iArray + len, print);
  cout << endl;
  return 0;
}

  

00TOP00

 

原文地址:https://www.cnblogs.com/xin-le/p/4120382.html