排序算法学习笔记

165 阅读2分钟

今天主要学习了algorithm里的一些函数

首先有sort函数:

sort(a.begin(), a.end());      // O(nlogn)
sort(a.begin(), a.end(), cmp); // O(nlogn)

begin、end分别表示需要排序位置的首末。
cmp是一个可选参数,可以自定义排序的比较方法。

排序之后,可以使用以下算法:
去重:

unique(a.begin(), a.end()); // O(n)

这个函数会返回去重后的序列末尾地址(序列长度可能会变短)。

查找:

find(a.begin(), a.end(), val); // O(logn)

若元素存在则返回元素地址,否则返回末尾地址(end)。

例题:洛谷 P1059 明明的随机数

给出 𝑁(𝑁 ≤ 100) 个 11000 的数字,输出去重后剩余数字的个数,以及去重排序后的序列。

代码:

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

int main(){
	int n;
	cin >> n;
	int a[n+5];
	for(int i = 0;i < n;i++)
		scanf("%d",&a[i]);
	sort(a,a+n);
	int cnt = unique(a,a+n) - a;
	cout << cnt << endl;
	for(int i = 0;i < cnt;i++)
		printf("%d ",a[i]);
	
	return 0;
}

自定义排序

sort 函数可以增加第三个参数 cmp,也就是自定义排序的基准。cmp 函数需要两个待排序的元素类型 a、b 作为参数。返回一个 bool 值,表示 x 是否严格小于 y。

例如:实现整数从大到小排序。

bool cmp(int x, int y){  
    return x > y;  
}
sort(a, a + n, cmp);

用cmp就可以对结构体进行排序,例如下面例题:

洛谷 P1093 奖学金:

给出 n(n≤300) 名学生的语文、数学、英语成绩,这些学生的学号依次是从 1 到 n。需要对这些学生进行排序。
如果总分相同,则语文分数高者名次靠前;如果语文成绩还是一样的,学号小者靠前。
输出排名前 5 的学生学号和总分。

代码:

#include<iostream>
#include<algorithm>
#define maxn 310
using namespace std;
struct student{
	int id,chinese,total;
}a[maxn];

bool cmp(student a,student b){
	if(a.total != b.total)
		return a.total > b.total;
	if(a.chinese != b.chinese)
		return a.chinese > b.chinese;
	return a.id < b.id;
}

int main(){
	int n,temp;
	cin >> n;
	for(int i = 0;i < n;i++){
		a[i].id = i+1;
		scanf("%d%d",&a[i].chinese,&temp);
		a[i].total = a[i].chinese + temp;
		scanf("%d",&temp);
		a[i].total += temp;
	}
	sort(a,a+n,cmp);
	for(int i = 0;i < 5;i++)
		printf("%d %d\n",a[i].id,a[i].total);
	
	return 0;
}

构造一个结构体 student 用户存储学生的各项有用的信息(数学和英语并不重要,可以不用存下来)。注意使用 cmp 来进行比较,当两个学生比较时,排名比较高的学生返回 true。