【C++】机试刷题总结day12——三、排序和查找——排序

三、排序和查找

排序

机试考点:直接用排序的算法
c语言:qsort
c++:sort(主要)
关键点:compare函数什么时候不发生交换

c++:sort

STL的算法
头文件algorithm算法头文件

#include <algorithm>
sort函数的功能:排序

(1)可以排序的数据结构:静态数组、动态数组vector(map、set意义不大,本身就有序)
(2)sort可以自定义排序规则
升序、降序或自定义规则

1、静态数组

sort函数(数组名,数组名+数组长度
第一个参数:数组首地址
第二个参数:尾后地址,最后一个地址的后一个地址
范围左闭右开

	//静态数组
	int arr[6] = {2,4,6,1,3,5};
	sort(arr, arr + 6);//第一个参数:数组首地址 第二个参数:尾后地址,最后一个地址的后一个地址 
2、动态数组vector

sort函数(数组名.begin(),数组名.end()
这里的参数为迭代器
参数范围相同

	//动态数组vector 
	vector<int> vec= {2,4,6,1,3,5};
	sort(vec.begin(), vec.end());//第一个参数:数组首地址 第二个参数:尾后地址,最后一个地址的后一个地址
3、自定义排序规则

sort函数底层:快速排序(小于枢纽放左边,大于枢纽放右边,基于比较
一定存在:
lhs代表左边指向的内容,rhs代表右边指向的内容

if(lhs 比较 rhs){//默认比较是小于<
	不交换
}else{
	交换
}

默认比较是小于<(升序)

自定义函数(),两个参数lhs和rhs,返回bool值(true\false)
函数体内是不发生交换的条件
主函数内调用sort函数,有三个参数,第三个参数是自定义的函数名

bool compare(int lhs,int rhs){//自定义排序——降序    两个参数,返回bool值(true\false)
	return lhs >= rhs;//比较左边和右边的大小 
}

	//自定义排序——降序
	sort(vec.begin(), vec.end(), compare);//三个参数,第三个参数是自定义的函数 
compare函数设计方案

(1)函数形式与返回值
返回bool值(true\false),两个参数lhs和rhs,参数类型和容器一直(int型写int,char型写char)

bool compare(int lhs,int rhs)

(2)当lhs和rhs不发生交换时,返回true

例题1、整数奇偶排序

思路:判断不交换的情况

(1)左奇 右偶
(2)左奇 右奇 且 左>右
(3)左偶 右偶 且 左<右

代码:
#include <stdio.h>
#include <algorithm>
using namespace std;

bool compare(int lhs, int rhs){
	if(lhs % 2 == 1 && rhs % 2 == 0){
		return true;
	}else if(lhs % 2 == 1 && rhs % 2 == 1 && lhs > rhs){
		return true;
	}else if(lhs % 2 == 0 && rhs % 2 == 0 && lhs < rhs){
		return true;
	}else{
		return false;
	}
}

int main(){
	int arr[10];
	for(int i = 0; i < 10; i++){
		scanf("%d", &arr[i]);//放到具体每个元素里面 &arr[i] 或者写成arr+i 
	}
	sort(arr, arr+10, compare);
	for(int i = 0; i < 10; i++){
		printf("%d ", arr[i]);
	}
	printf("\n");
	
	return 0;
}

例题2、成绩排序2

思路:

(1)不是单个信息,创造一个类保存信息

//定义自定义类型
struct Student{
	int number;
	int score;
}; 

(2)自定义sort函数排序
(3)用vector数组

代码:
#include <stdio.h>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
//定义自定义类型
struct Student{
	int number;
	int score;
}; 

bool compare(Student lhs, Student rhs){
	if(lhs.score < rhs.score){
		return true;
	}else if(lhs.score == rhs.score && lhs.number < rhs.number){
		return true;
	}else{
		return false;
	}
}

int main(){
	int n;
	scanf("%d", &n);
	vector<Student> vec(n);//维持一个动态数组 
	for(int i = 0; i < n; i++){
		scanf("%d%d", &vec[i].number, &vec[i].score);//%d之间不用逗号隔开   .运算符是访问类的成员 
	}
	sort(vec.begin(), vec.end(), compare);
	for(int i = 0; i < n; i++){
		printf("%d %d\n", vec[i].number, vec[i].score);
	}
	return 0;
}

例题3、成绩排序※

关键点:

(1)可选排序方式——>两个compare函数
(2)原始成绩单中靠前的学生排列在前——>稳定排序
解决方法:
<1>标准库的stable_sort函数
<2>改造sort函数

易错点:

(1)长度不超过 10的小写字母构成的字符串——>至少11个字符,还有终止符——>多一点最好

char name[20];//长一点,不要小于11

(2)比较稳定性——>结构体内多一个序号成员,比较时纳入序号规则

struct Student{
	char name[20];//长一点,不要小于11
	int score;
	//实现稳定排序
	int seq;//序号,比较时纳入序号规则 
};

else if(lhs.score == rhs.score && lhs.seq < rhs.seq){
		return true;
}

(3)输入到字符数组无需取地址(name)

scanf("%s%d", vec[i].name, &vec[i].score);//name无需取地址,因为name本身是字符数组 
代码:
#include <stdio.h>
#include <algorithm>
using namespace std;

struct Student{
	char name[20];//长一点,不要小于11
	int score;
	//实现稳定排序
	int seq;//序号,比较时纳入序号规则 
};

bool compare0(Student lhs, Student rhs){//高到低 
	if(lhs.score > rhs.score){
		return true;
	}else if(lhs.score == rhs.score && lhs.seq < rhs.seq){
		return true;
	}else{
		return false;
	}
}
bool compare1(Student lhs, Student rhs){//低到高 
	if(lhs.score < rhs.score){
		return true;
	}else if(lhs.score == rhs.score && lhs.seq < rhs.seq){
		return true;
	}else{
		return false;
	}
}

int main(){
	int n;
	scanf("%d", &n);
	int flag = -1;//排序规则
	scanf("%d", &flag);
//	Student student[n];
	vector<Student> vec(n);
	for(int i = 0; i < n; i++){
		scanf("%s%d", vec[i].name, &vec[i].score);//name无需取地址,因为name本身是字符数组 
		vec[i].seq = i;
	}
	
	if(0 == flag){
		sort(vec.begin(), vec.end(), compare0);
	}else{
		sort(vec.begin(), vec.end(), compare1);
	}
	
	for(int i = 0 ; i < n; i++){
		printf("%s %d\n", vec[i].name, vec[i].score);
	}
	return 0;
}
  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值