C++中STL算法之排序算法——sort

文章目录

        • 1.排序算法介绍
          • 1.1 对所有元素进行排序
          • 1.2 局部排序
          • 1.3 自带的一些比较准则
        • 2.排序算法的常见用法
          • 2.1 标准元素的排序
          • 2.2 自定义的元素排序
            • 2.2.1 写比较函数
            • 2.2.2 编写运算符重载函数
            • 2.2.3 自定义外部比较类或者结构体

1.排序算法介绍

STL提供的排序算法主要包含以下几个:

函数名 功能描述
sort() 对给定区间所有元素进行排序
stable_sort() 对给定区间所有元素进行稳定排序,即保持想等元素间的相对次序
partial_sort() 对给定区间所有元素部分排序
nth_element() 找出给定区间的某个位置对应的元素
is_sorted 判断一个区间是否已经排好序
  • 所有的sort算法的参数都需要输入一个范围,[begin, end)
  • 使用的迭代器(iterator)都需是随机迭代器(RadomAccessIterator), 也就是说可以随机访问的迭代器,(partition 和stable_partition 除外)
  • 可以传入自己的比较准则(op),尤其是自己定义比较结构体的时候
1.1 对所有元素进行排序

经过优化的快速排序算法:
sort(begin,end)
sort(begin,end,op)

使用归并排序算法:
stable_sort(begin,end)
stable_sort(begin,end,op)

1)不带op参数的版本使用<("小于"运算符)对区间[begin,end)内的所有元素排序
2)带op参数的版本使用op(elem1,elem2)为准则对区间[begin,end)内的所有元素进行排序
3)sort和stable_sort()的区别的是,后者保持想等元素原来的相对次序
4)不能对list调用这些算法,因为list不支持随机存取迭代器

1.2 局部排序

使用堆排序算法:(局部排序)
partial_sort(begin,sortEnd,end)
partial_sort(begin,sortEnd,end,op)

1)不带op参数的版本使用<("小于"运算符)对区间[begin,end)内的元素排序,使得区间[begin,sortEnd)内的元素有序
2)带op参数的版本使用op(elem1,elem2)为准则对区间[begin,end)内的所有元素进行排序,
3)使得区间[begin,sortEnd)内的元素有序

根据第n个位置排序(快速排序算法):
nth_element(beg,nth,end)
nth_element(beg,nth,end,op)

1)对区间[beg,end)内的元素排序,使所有在位置n之前的元素都小于等于它,所有位置在n之后的元素都大于等于它,从而得到两个分割开的子序列,但子序列不一定有序。(和一趟快速排序一样)
2)不带op参数的使用<运算符作为排序准则
3)带op参数的使用op(elem1,elem2)作为排序准则
4)可以找到找出给定区间的第n个位置对应的元素

1.3 自带的一些比较准则

提供了一些比较函数,但是私认为自己写比较方便:

名称 功能描述
equal_to 相等
not_equal_to 不相等
less 小于
greater 大于
less_equal 小于等于
greater_equal 大于等于

默认使用的是less,但是需要注意,这些函数并不是都适用与你的sort算法,且不能直接写入比较函数的名字,而是要写重载的()函数,比如:

less()
greater()

2.排序算法的常见用法

Sort函数使用模板:
头文件是#include
Sort(start,end,排序方法)

2.1 标准元素的排序
#include
#include
#include

using namespace std;

int cmp1(int a, int b) {
	return a > b;
}
void showarr(int* a,int len) {
	for (int i = 0; i < len; i++) cout << a[i] << " ";
	cout << endl;
}
int main()
{
	int a[10] = { 9,6,3,8,5,2,7,4,1,0 };
	cout << "排序前:"; showarr(a,10);

	sort(a, a + 10);//默认升序排列
	cout << "默认升序后:"; showarr(a,10);
	
	sort(a, a + 10, cmp1);
	//sort(a, a + 10, greater());也是可以的
	cout << "降序后:"; showarr(a,10);
	
	system("pause");
	return 0;
}
2.2 自定义的元素排序
2.2.1 写比较函数
#include
#include
#include
#include

using namespace std;
//学生结构体
struct student {
	string name;
	int age;
};
//自定义排序规则,名字优先,年龄次之
int cmp(student s1, student s2) {
	return s1.name < s2.name || (s1.name == s2.name && s1.age < s2.age);
}
int main()
{
	student s[4];
	s[0].name = "mike"; s[0].age = 11;
	s[1].name = "mike"; s[1].age = 21;
	s[2].name = "jack"; s[2].age = 11;
	s[3].name = "jack"; s[3].age = 40;

	sort(s, s + 4, cmp);
	cout << "名字 年龄\n";
	for (int i = 0; i < 4; i++) {
		cout << s[i].name << " " << s[i].age << " " << endl;;
	}

	system("pause");
	return 0;
}
2.2.2 编写运算符重载函数
<返回类型说明符> operator <运算符符号>(<参数表>)
{
     <函数体>
}
#include
#include
#include
#include

using namespace std;
//学生结构体
struct student {
	string name;
	int age;
	bool operator < (student s2) const {
		return this->name < s2.name || (this->name == s2.name && this->age < s2.age);
	}
};
int main()
{
	student s[4];
	s[0].name = "mike"; s[0].age = 11;
	s[1].name = "mike"; s[1].age = 21;
	s[2].name = "jack"; s[2].age = 11;
	s[3].name = "jack"; s[3].age = 40;

	sort(s, s + 4);
	cout << "名字 年龄\n";
	for (int i = 0; i < 4; i++) {
		cout << s[i].name << " " << s[i].age << " " << endl;;
	}

	system("pause");
	return 0;
}
2.2.3 自定义外部比较类或者结构体
#include
#include
#include
#include

using namespace std;
//学生结构体
struct student {
	string name;
	int age;
};
//比较结构体
struct Less {
	int operator ()(const student& s1,const student& s2){
		return s1.name < s2.name || (s1.name == s2.name && s1.age < s2.age);
	}
};
int main()
{
	student s[4];
	s[0].name = "mike"; s[0].age = 11;
	s[1].name = "mike"; s[1].age = 21;
	s[2].name = "jack"; s[2].age = 11;
	s[3].name = "jack"; s[3].age = 40;

	sort(s, s + 4,Less());
	cout << "名字 年龄\n";
	for (int i = 0; i < 4; i++) {
		cout << s[i].name << " " << s[i].age << " " << endl;;
	}

	system("pause");
	return 0;
}

注意!!!
比较准则的书写要保持严格弱序(strict weak ordering)的规则:
1.两个关键字不能同时“严格弱序”于对方;
2.如果a“严格弱序”于b,且b“严格弱序”于c,则a必须“严格弱序”于c;
3.如果存在两个关键字,任何一个都不“严格弱序”于另一个,则这两个关键字是相等的。

就好比:
“<” 和 “>” 是严格弱序的,但是换成 “<=” 和 “>=” 却不行。

你可能感兴趣的:(#,C++基础知识)