#include // std::cout
#include // std::sort
#include // std::vector
//以普通函数的方式实现自定义排序规则
bool mycomp(int i, int j) {
return (i < j);
}
//以函数对象的方式实现自定义排序规则
class mycomp2 {
public:
bool operator() (int i, int j) {
return (i < j);
}
};
int main() {
std::vector<int> myvector{ 32, 71, 12, 45, 26, 80, 53, 33 };
//调用第一种语法格式,对 32、71、12、45 进行排序
std::sort(myvector.begin(), myvector.begin() + 4); //(12 32 45 71) 26 80 53 33
//调用第二种语法格式,利用STL标准库提供的其它比较规则(比如 greater)进行排序
std::sort(myvector.begin(), myvector.begin() + 4, std::greater<int>()); //(71 45 32 12) 26 80 53 33
//调用第二种语法格式,通过自定义比较规则进行排序
std::sort(myvector.begin(), myvector.end(), mycomp2());//12 26 32 33 45 53 71 80
//输出 myvector 容器中的元素
for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it) {
std::cout << *it << ' ';
}
return 0;
}
//排序规则采用默认的升序排序
void nth_element (RandomAccessIterator first,
RandomAccessIterator nth,
RandomAccessIterator last);
//排序规则为自定义的 comp 排序规则
void nth_element (RandomAccessIterator first,
RandomAccessIterator nth,
RandomAccessIterator last,
Compare comp);
有一个存有 100 万个元素的容器,但我们只想从中提取出值最小的 10 个元素,该如何实现呢?
//按照默认的升序排序规则,对 [first, last) 范围的数据进行筛选并排序
void partial_sort (RandomAccessIterator first,
RandomAccessIterator middle,
RandomAccessIterator last);
//按照 comp 排序规则,对 [first, last) 范围的数据进行筛选并排序
void partial_sort (RandomAccessIterator first,
RandomAccessIterator middle,
RandomAccessIterator last,
Compare comp);
1 . partial_sort() 函数会以交换元素存储位置的方式实现部分排序的。具体来说,partial_sort() 会将 [first, last) 范围内最小(或最大)的 middle-first 个元素移动到 [first, middle) 区域中,并对这部分元素做升序(或降序)排序。
2. partial_sort采用的堆排序(heapsort),它在任何情况下的复杂度都是n*log(n). 如果你希望用partial_sort来实现全排序,你只要让middle=last就可以了。
参考下面的方法:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* merge(ListNode *head1,ListNode *head2) {
ListNode *n_head=new ListNode(0);
ListNode *h_head=n_head;
while(head1!=nullptr && head2!=nullptr) {
if(head1->val<head2->val) {
ListNode *temp=head1->next;
h_head->next=head1;
head1=temp;
} else if(head1->val>head2->val) {
ListNode *temp=head2->next;
h_head->next=head2;
head2=temp;
} else {
ListNode *temp=head1->next;
ListNode *temp1=head2->next;
h_head->next=head1;
h_head=h_head->next;
h_head->next=head2;
head1=temp;
head2=temp1;
}
h_head=h_head->next;
}
if(head1!=nullptr) {
h_head->next=head1;
} else if(head2!=nullptr) {
h_head->next=head2;
} else h_head->next=nullptr;
return n_head->next;
}
ListNode *helper(ListNode* head,ListNode *tail) {
if(head==nullptr) return head;
if(head->next==tail) {
head->next=nullptr;
return head;
}
ListNode *slow=head,*fast=head;
while(fast!=tail) {
slow=slow->next;
fast=fast->next;
if(fast!=tail) {
fast=fast->next;
}
}
ListNode *mid=slow;
return merge(helper(head,mid),helper(mid,tail));
}
ListNode* sortList(ListNode* head) {
return helper(head,nullptr);
}
};
说明:
1.归并,找到中间值用的快慢指针
2. 但实际STL里面的排序用的是非递归的归并,代码可参考:
https://blog.csdn.net/qq_31720329/article/details/85535787
3. 如果对std::list做排序用std::sort,那么实际上随机访问数值时需要逐个获取,时间复杂度也相当于n^2了
性能优势
对于排序算法,使用函数对象编译器可以直接进行内联,减少函数调用次数。而使用普通函数时,传入算法内部的实际是函数指针,编译器无法对其进行优化。
借助 merge() 或者 inplace_merge() 函数实现。
//以默认的升序排序作为排序规则
OutputIterator merge (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result);
//以自定义的 comp 规则作为排序规则
OutputIterator merge (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp);
std::vector<int> find_if_vec{4,2,3,1,5};
auto find_if_it = std::find_if(find_if_vec.begin(), find_if_vec.end(), [](int a){return a%2 == 0;});
std::cout << "find_if_it : " << *find_if_it << std::endl;
/* find_if_it : 4 */
关于 search() 函数和 search_n() 函数的区别,给大家举个例子,下面有 3 个序列:
序列 A:1,2,3,4,4,4,1,2,3,4,4,4
序列 B:1,2,3
序列 C:4,4,4
如果想查找序列 B 在序列 A 中第一次出现的位置,就只能使用 search() 函数;而如果想查找序列 C 在序列 A 中第一次出现的位置,既可以使用 search() 函数,也可以使用 search_n() 函数。
ForwardIterator partition (ForwardIterator first,
ForwardIterator last,
UnaryPredicate pred);
#include // std::cout
#include // std::partition
#include // std::vector
using namespace std;
//以普通函数的方式定义partition()函数的筛选规则
bool mycomp(int i) { return (i % 2) == 0; }
//以函数对象的形式定义筛选规则
class mycomp2 {
public:
bool operator()(const int& i) {
return (i%2 == 0);
}
};
int main() {
std::vector<int> myvector{1,2,3,4,5,6,7,8,9};
std::vector<int>::iterator bound;
//以 mycomp2 规则,对 myvector 容器中的数据进行分组
bound = std::partition(myvector.begin(), myvector.end(), mycomp2());
for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it) {
cout << *it << " ";
}
cout << "\nbound = " << *bound;
return 0;
}
std::vector<int> lower_bound_vec{4,5,3,1,2};
auto lower_bound_vec_it = std::lower_bound(lower_bound_vec.begin(), lower_bound_vec.end(), 3, [](int i, int j) {return i >j; });
std::cout<< "lower_bound_vec_it = " << *lower_bound_vec_it<<std::endl;
/* 3 */
用于在指定范围内查找大于目标值的第一个元素。
举个例子,假设 有一个数组num:
1 2 2 2 3 4 5
value = 2
lower_bound 得到的是num[1]
uppper_bound得到的是nun[4]
//找到 [first, last) 范围中所有等于 val 的元素
pairequal_range (ForwardIterator first, ForwardIterator last, const T& val);
std::vector<int> none_of_vec{22, 19, 46, 75, 54, 19, 27, 66, 61, 33, 22, 19};
std::cout << "There are "
<< (std::none_of(none_of_vec.begin(), none_of_vec.end(), [](const int &i){return i == 18;}) ? "no" : "some")
<< " student age = 18 ."
<< std::endl;
/* There are no student age = 18 .*/
std::vector<int> none_of_vec{22, 19, 46, 75, 54, 19, 27, 66, 61, 33, 22, 19};
std::cout << "There are "
<< (std::none_of(none_of_vec.begin(), none_of_vec.end(), [](const int &i){return i == 18;}) ? "no" : "some")
<< " student age = 18 ."
<< std::endl;
/* There are no student age = 18 .*/
std::vector<std::string> names {"A1","George" ,"Harry", "Iain", "Beth","Carol", "Eve","Dan", "Joe","Fred"};
std::unordered_set<std::string> more_names {"Janet", "John"};
std::copy_n(std::rbegin(names)+1, 3, std::inserter(more_names, std::begin(more_names)));
/*
[0] = "Eve"
[1] = "Dan"
[2] = "Joe"
[3] = "John"
[4] = "Janet"
*/