排序类算法及基于排序的算法
这部分主要介绍常用的排序算法和基于排序的算法。
排序类算法
STL中提供里提供了很多种排序算法,包括了全局排序以及部分排序。这里需要注意的是排序算法需要能够随机访问范围内的元素,
所以标准库中list、associative containers、unorder containers都不在算法支持的范围内。当然associative containers
依然可以根据key值自动完成排序。常见排序算法:
操作 | 说明 |
---|---|
sort(beg,end) | 对[beg,end)范围内的元素进行排序(默认规则为<,可以自定义规则作为第3个参数) |
stable_sort(beg,end) | 对[beg,end)范围内的元素进行排序(默认规则为<,可以自定义规则作为第3个参数) |
partial_sort(beg,des,end) | 对[beg,end)元素进行排序并且都小于des所指元素值(可自定义规则) |
partial_sort_copy(beg,end,beg2,end2) | 将[beg,end)中end2-beg2个最小的元素拷贝到[beg2,end2)并排序 |
is_sorted(beg,end) | 判断[beg,end)是否有序(默认为<,可自定义排序规则) |
is_sorted_until(beg,end) | 查找从beg开始的第一个无序元素的位置(默认为<,可自定义排序规则) |
nth_element(beg,n,end) | 将[beg,end)分为两部分[beg,n)、[n+1,end)前者都不大于,后者小于n所指元素(可自定义规则) |
基于排序的二分搜索
操作 | 说明 |
---|---|
lower_bound(beg,end,val) | 对于[beg,end)的有序序列返回第一个大于等于val元素的位置(可自定义规则作为第四参数) |
upper_bound(beg,end,val) | 对于[beg,end)的有序序列返回第一个大于val元素的位置(可自定义规则) |
equal_range(beg,end,val) | 对于[beg,end)的有序序列返回所有等于val元素的范围也就是上面两个函数所在区域(可自定义规则) |
binary_search(beg,end,val) | 对于[beg,end)有序序列二分搜索,判断是否有值为val的元素(可自定义规则) |
基于排序的合并算法
操作 | 说明 |
---|---|
merge(beg1,end1,beg2,end2,des) | 将有序序列[beg1,end1)、[beg2,end2)合并到des并有序(可自定义规则,默认<) |
set_union(beg1,end1,beg2,end2,des) | 将有序序列[beg1,end1)、[beg2,end2)交集合并到des并有序(可自定义规则,默认<) |
set_intersection(beg1,end1,beg2,end2,des) | 将有序序列[beg1,end1)、[beg2,end2)并集合并到des并有序(可自定义规则,默认<) |
set_difference(beg1,end1,beg2,end2,des) | 将有序序列[beg1,end1)-[beg2,end2)差集合并到des并有序(可自定义规则,默认<) |
set_symmetric_difference(beg1,end1,beg2,end2,des) | 将有序序列[beg1,end1)、[beg2,end2)中对称差(A-B) U (B-A)排序后放入des(可自定义规则) |
代码示例
#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() {
vector<int> myvector{ 32, 71, 12, 45, 26, 80, 53, 33 };; // 32 71 12 45 26 80 53 33
// 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 (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
std::cout << *it << ' ';
cout << endl;
return 0;
}
//output:
//myvector contains: 12 26 32 33 45 53 71 80
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
bool myfunction(int i, int j) { return (i<j); }
int main() {
vector<int> myvector{ 9, 8, 7, 6, 5, 4, 3, 2, 1 };;
// 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 (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
cout << *it << ' ';
cout << endl;
return 0;
}
//output:
//myvector contains: 1 2 3 4 5 9 8 7 6
// lower_bound/upper_bound example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
vector<int> v{ 10, 20, 30, 30, 20, 10, 10, 20 }; // 10 20 30 30 20 10 10 20
sort(v.begin(), v.end()); // 10 10 10 20 20 20 30 30
vector<int>::iterator low, up;
low = lower_bound(v.begin(), v.end(), 20); // ^
up = upper_bound(v.begin(), v.end(), 20); // ^
cout << "lower_bound at position " << (low - v.begin()) << '\n';
cout << "upper_bound at position " << (up - v.begin()) << '\n';
return 0;
}
//output:
//lower_bound at position 3
//upper_bound at position 6
// 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
v.resize(it - v.begin()); // 5 10 15 20 25 30 40 50
cout << "The union has " << (v.size()) << " elements: ";
for (it = v.begin(); it != v.end(); ++it)
cout << *it << ' ';
cout <<endl;
return 0;
}
//output:
//The union has 8 elements: 5 10 15 20 25 30 40 50
// 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);
sort(first, first + 5);
sort(second, second + 5);
merge(first, first + 5, second, second + 5, v.begin());
cout << "The resulting vector contains: ";
for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
cout << *it << ' ';
cout << '\n';
return 0;
}
//output:
//The resulting vector contains: 5 10 10 15 20 20 25 30 40 50
// set_symmetric_difference example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
int first[] = { 5, 15, 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
v.resize(it - v.begin()); // 5 15 25 30 40 50
cout << "The symmetric difference has " << (v.size()) << " elements: "<<endl;
for (it = v.begin(); it != v.end(); ++it)
cout << ' ' << *it;
cout << endl;
return 0;
}
//otput:
//The symmetric difference has 8 elements:
//5 10 15 15 35 30 40 50
版权声明:本文为博主原创文章,未经博主允许不得转载。