C++排序(sort;stable_sort;partial_sort;partial_sort_copy;is_sorted;is_sorted_until;nth_element)

一、sort

头文件algorithm

default (1)	
template <class RandomAccessIterator>
  void sort (RandomAccessIterator first, RandomAccessIterator last);
custom (2)	
template <class RandomAccessIterator, class Compare>
  void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

排序范围内的元素
将[first,last]范围内的元素按升序排序。

使用operator <作为第一个版本比较元素,comp作为第二个版本。

不保证等效元素保持其原始相对顺序(请参阅stable_sort)。

参数

  1. first,last
    随机访问迭代器到要排序的序列的初始和最终位置。使用的范围是[first,last),它包含first和last之间的所有元素,包括first指向的元素,但不包括last指向的元素。
    RandomAccessIterator应指向一个正确定义了swap的类型,它既可移动构造又可移动分配。
  2. comp
    二进制函数,接受范围中的两个元素作为参数,并返回可转换为bool的值。返回的值表示作为第一个参数传递的元素是否被认为是在它定义的特定严格弱顺序中的第二个参数之前。
    该函数不得修改其任何参数。这可以是函数指针或函数对象。

返回值

没有

// sort example
#include <iostream>     // std::cout
#include <algorithm>    // std::sort
#include <vector>       // std::vector

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};
  std::vector<int> myvector (myints, myints+8);               // 32 71 12 45 26 80 53 33

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

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

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

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

在这里插入图片描述

复杂度

平均而言,第一个和最后一个之间的距离是线性的:执行大约N * log2(N)(其中N是这个距离)元素的比较,直到那么多元素交换(或移动)。

例外

如果任何元素比较,元素交换(或移动)或迭代器上的操作抛出,则抛出。
请注意,无效参数会导致未定义的行为。

二、stable_sort

头文件algorithm

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

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

排序元素保留等价的顺序
将[first,last]范围内的元素按升序排序,如sort,但stable_sort保留具有等效值的元素的相对顺序。

使用operator <作为第一个版本比较元素,comp作为第二个版本。

参数

  1. first,last
    随机访问迭代器到要排序的序列的初始和最终位置。使用的范围是[first,last),它包含first和last之间的所有元素,包括first指向的元素,但不包括last指向的元素。
    RandomAccessIterator应指向一个正确定义了swap的类型,它既可移动构造又可移动分配。
  2. comp
    二进制函数,接受范围中的两个元素作为参数,并返回可转换为bool的值。返回的值表示作为第一个参数传递的元素是否被认为是在它定义的特定严格弱顺序中的第二个参数之前。
    该函数不得修改其任何参数。这可以是函数指针或函数对象。

返回值

没有

// stable_sort example
#include <iostream>     // std::cout
#include <algorithm>    // std::stable_sort
#include <vector>       // std::vector

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};

  std::vector<double> myvector;

  myvector.assign(mydoubles,mydoubles+8);

  std::cout << "using default comparison:";
  std::stable_sort (myvector.begin(), myvector.end());
  for (std::vector<double>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  myvector.assign(mydoubles,mydoubles+8);

  std::cout << "using 'compare_as_ints' :";
  std::stable_sort (myvector.begin(), myvector.end(), compare_as_ints);
  for (std::vector<double>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

在这里插入图片描述

compare_as_ints是一个仅比较元素的整数部分的函数,因此,具有相同整数部分的元素被认为是等效的。
stable_sort保留调用之前的相对顺序。

复杂度

如果有足够的额外内存可用,则第一个和最后一个之间的距离为线性:执行最多N * log2(N)个元素比较(其中N是此距离),最多可执行多个元素移动。
否则,该距离中的多线性:执行N * log22(N)个元素比较,最多执行那么多元素交换。

例外

如果任何元素比较,元素交换(或移动)或迭代器上的操作抛出,则抛出。
请注意,无效参数会导致未定义的行为。

三、partial_sort

头文件algorithm

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

对范围内的元素进行部分排序
重新排列[first,last]范围内的元素,使得中间的元素是整个范围中的最小元素,并按升序排序,而其余元素没有任何特定顺序。

使用operator <作为第一个版本比较元素,comp作为第二个版本。

参数

  1. first,last
    随机访问迭代器到序列的初始和最终位置以进行部分排序。使用的范围是[first,last),它包含first和last之间的所有元素,包括first指向的元素,但不包括last指向的元素。
    请注意,在此函数中,这些不是连续参数,而是第一个和第三个参数。
  2. middle
    随机访问迭代器,指向范围[first,last]中的元素,该元素用作完全排序的元素的上边界。
  3. comp
    二进制函数,接受范围中的两个元素作为参数,并返回可转换为bool的值。返回的值表示作为第一个参数传递的元素是否被认为是在它定义的特定严格弱顺序中的第二个参数之前。
    该函数不得修改其任何参数。这可以是函数指针或函数对象。

RandomAccessIterator应指向一个正确定义了swap的类型,它既可移动构造又可移动分配。

返回值

没有

// partial_sort example
#include <iostream>     // std::cout
#include <algorithm>    // std::partial_sort
#include <vector>       // std::vector

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

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

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

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

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

在这里插入图片描述

复杂度

平均而言,在第一个和最后一个之间的距离中小于线性:执行大约N * log(M)个元素的比较(其中N是该距离,M是第一个和中间之间的距离)。 它还可以执行多个元素交换(或移动)。

例外

如果任何元素比较,元素交换(或移动)或迭代器上的操作抛出,则抛出。
请注意,无效参数会导致未定义的行为。

四、partial_sort_copy

头文件algorithm

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

复制和部分排序范围
将[first_ last]范围内的最小元素复制到[result_first,result_last],对复制的元素进行排序。复制的元素数与result_first和result_last之间的距离相同(除非这超过[first,last)中的元素数量)。

范围[first,last]不会被修改。

使用operator <作为第一个版本比较元素,comp作为第二个版本。

参数

  1. first,last
    将迭代器输入到要复制的序列的初始位置和最终位置。使用的范围是[first,last),它包含first和last之间的所有元素,包括first指向的元素,但不包括last指向的元素。
    InputIterator应指向可分配给RandomAccessIterator指向的元素的类型。
  2. result_first,result_last
    随机访问迭代器到目标序列的初始和最终位置。使用的范围是[result_first,result_last)。
    RandomAccessIterator应指向一个正确定义了swap的类型,它既可移动构造又可移动分配。
  3. comp
    二进制函数,它接受结果范围中的两个元素作为参数,并返回一个可转换为bool的值。返回的值表示作为第一个参数传递的元素是否被认为是在它定义的特定严格弱顺序中的第二个参数之前。
    该函数不得修改其任何参数。这可以是函数指针或函数对象。

返回值

一个迭代器,指向结果序列中写入的最后一个元素后面的元素。

// partial_sort_copy example
#include <iostream>     // std::cout
#include <algorithm>    // std::partial_sort_copy
#include <vector>       // std::vector

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

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

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

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

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

在这里插入图片描述

复杂度

平均而言,第一个和最后一个之间的距离小于线性:执行大约N * log(min(N,M))元素的比较(其中N是此距离,M是result_first和result_last之间的距离)。 它还可以在范围之间执行多达元素交换(或移动)和最小(N,M)分配。

例外

如果任何元素比较,元素赋值,元素交换(或移动)或迭代器上的操作抛出,则抛出。
请注意,无效参数会导致未定义的行为。

五、is_sorted

default (1)	
template <class ForwardIterator>
  bool is_sorted (ForwardIterator first, ForwardIterator last);
custom (2)	
template <class ForwardIterator, class Compare>
  bool is_sorted (ForwardIterator first, ForwardIterator last, Compare comp);

检查范围是否已排序

如果范围[first,last]按升序排序,则返回true。

使用operator <作为第一个版本比较元素,comp作为第二个版本。

此函数模板的行为等效于:

template <class ForwardIterator>
  bool is_sorted (ForwardIterator first, ForwardIterator last)
{
  if (first==last) return true;
  ForwardIterator next = first;
  while (++next!=last) {
    if (*next<*first)     // or, if (comp(*next,*first)) for version (2)
      return false;
    ++first;
  }
  return true;
}

参数

  1. first,last
    将迭代器转发到序列的初始和最终位置。 检查的范围是[first,last),它包含first和last之间的所有元素,包括first指向的元素,但不包括last指向的元素。
  2. comp
    二进制函数,接受范围中的两个元素作为参数,并返回可转换为bool的值。 返回的值表示作为第一个参数传递的元素是否被认为是在它定义的特定严格弱顺序中的第二个参数之前。
    该函数不得修改其任何参数。这可以是函数指针或函数对象。

返回值

如果范围[first,last]按升序排序,则为true,否则为false。
如果范围[first,last]包含少于两个元素,则该函数始终返回true。

// is_sorted example
#include <iostream>     // std::cout
#include <algorithm>    // std::is_sorted, std::prev_permutation
#include <array>        // std::array

int main () {
  std::array<int,4> foo {2,4,1,3};

  do {
    // try a new permutation:
    std::prev_permutation(foo.begin(),foo.end());

    // print range:
    std::cout << "foo:";
    for (int& x:foo) std::cout << ' ' << x;
    std::cout << '\n';

  } while (!std::is_sorted(foo.begin(),foo.end()));

  std::cout << "the range is sorted!\n";

  return 0;
}

在这里插入图片描述

复杂度

最多比第一个和最后一个之间的距离小一些:比较元素对,直到找到不匹配。

例外

如果元素比较或迭代器上的操作抛出,则抛出。
请注意,无效参数会导致未定义的行为。

六、is_sorted_until

头文件algorithm

default (1)	
template <class ForwardIterator>
  ForwardIterator is_sorted_until (ForwardIterator first, ForwardIterator last);
custom (2)	
template <class ForwardIterator, class Compare>
  ForwardIterator is_sorted_until (ForwardIterator first, ForwardIterator last,
                                   Compare comp);

在范围内查找第一个未排序的元素

返回到[first,last]范围内第一个元素的迭代器,它不遵循升序。

返回的first和迭代器之间的范围已排序。

如果整个范围已排序,则该函数最后返回。

使用operator <作为第一个版本比较元素,comp作为第二个版本。

此函数模板的行为等效于:

template <class ForwardIterator>
  ForwardIterator is_sorted_until (ForwardIterator first, ForwardIterator last)
{
  if (first==last) return first;
  ForwardIterator next = first;
  while (++next!=last) {
    if (*next<*first) return next;
    ++first;
  }
  return last;
}

参数

  1. first,last
    将迭代器转发到序列中的初始位置和最终位置。 检查的范围是[first,last),它包含first和last之间的所有元素,包括first指向的元素,但不包括last指向的元素。
  2. comp
    二进制函数,接受范围中的两个元素作为参数,并返回可转换为bool的值。 返回的值表示作为第一个参数传递的元素是否被认为是在它定义的特定严格弱顺序中的第二个参数之前。
    该函数不得修改其任何参数。这可以是函数指针或函数对象。

返回值

范围中第一个元素的迭代器,不遵循升序,或者如果所有元素都已排序或范围包含少于两个元素,则为最后一个。

// is_sorted_until example
#include <iostream>     // std::cout
#include <algorithm>    // std::is_sorted_until, std::prev_permutation
#include <array>        // std::array

int main () {
  std::array<int,4> foo {2,4,1,3};
  std::array<int,4>::iterator it;

  do {
    // try a new permutation:
    std::prev_permutation(foo.begin(),foo.end());

    // print range:
    std::cout << "foo:";
    for (int& x:foo) std::cout << ' ' << x;
    it=std::is_sorted_until(foo.begin(),foo.end());
    std::cout << " (" << (it-foo.begin()) << " elements sorted)\n";

  } while (it!=foo.end());

  std::cout << "the range is sorted!\n";

  return 0;
}

在这里插入图片描述

复杂度

第一个和最后一个之间的距离最多为线性:为每个元素调用comp,直到找到不匹配为止。

例外

如果comp或迭代器上的操作抛出,则抛出。
请注意,无效参数会导致未定义的行为。

七、nth_element

头文件algorithm

default (1)	
template <class RandomAccessIterator>
  void nth_element (RandomAccessIterator first, RandomAccessIterator nth,
                    RandomAccessIterator last);
custom (2)	
template <class RandomAccessIterator, class Compare>
  void nth_element (RandomAccessIterator first, RandomAccessIterator nth,
                    RandomAccessIterator last, Compare comp);

排序范围内的元素

重新排列[first,last]范围内的元素,使得第n个位置的元素是在排序序列中处于该位置的元素。

除了nth之前的元素都不大于它之外,其他元素没有任何特定的顺序,并且其后面的元素都不会更少。

使用operator <作为第一个版本比较元素,comp作为第二个版本。

参数

  1. first,last
    Random-access iterator到要使用的序列的初始和最终位置。 使用的范围是[first,last),它包含first和last之间的所有元素,包括first指向的元素,但不包括last指向的元素。
    请注意,在此函数中,这些不是连续参数,而是第一个和第三个。
  2. nth
    【C ++11】
    Random-access iterator指向将包含已排序元素的范围[first,last]内的位置。
    请注意,在调用之前由第n个指向的元素的值是不相关的。
    【C++14】
    Random-access iterator指向将包含已排序元素的范围[first,last]内的位置。
    如果这指向最后,则函数调用无效。
    请注意,在调用之前由第n个指向的元素的值是不相关的。
  3. comp
    二进制函数,接受范围中的两个元素作为参数,并返回可转换为bool的值。 返回的值表示作为第一个参数传递的元素是否被认为是在它定义的特定严格弱顺序中的第二个参数之前。
    该函数不得修改其任何参数。这可以是函数指针或函数对象。

返回值

没有

// nth_element example
#include <iostream>     // std::cout
#include <algorithm>    // std::nth_element, std::random_shuffle
#include <vector>       // std::vector

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

int main () {
  std::vector<int> myvector;

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

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

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

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

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

在这里插入图片描述

复杂度

平均而言,第一个和最后一个之间的距离是线性的:比较元素,并可能交换(或移动)它们,直到元素被正确重新排列。

数据范围

[first,last]范围内的对象被修改。

例外

如果任何元素比较,元素交换(或移动)或迭代器上的操作抛出,则抛出。
请注意,无效参数会导致未定义的行为。

猜你喜欢

转载自blog.csdn.net/baidu_34884208/article/details/88054363