第二十四章:结构体与排序
结构体与排序
学习结构体与排序之前,请确保你已掌握一维数组和函数的相关知识。
一、为什么要使用结构体
回顾前面的知识,我们都知道,数组可以用来批量定义和操控具有相同数据类型的变量。比如,int a[10]这条语句中,a数组可以存储10个int 类型的变量。
但是
如果需要批量定义的变量数据类型不同呢?比如:要同时统计一个班上所有学生的信息,包括姓名(string),年龄(int),身高(float),等等。这个时候,如果还用数组来存储信息的话,我们需要至少3个数组,处理起来很不方便,这时就要用到结构体。
结构体是 自定义类型 ,它就像一个 能装不同数据类型 的“包裹”。当你声明一个结构体后,需要赋予这个结构体一个名字(即 结构体名 )。而 定义具体变量时,也可以定义结构体数组 。这相当于告诉计算机,你一口气定义了许多“包裹”,每一个“包裹”里面都可以装入许多不同或相同数据类型的变量。
举个例子
朱老师得知拓拓是个编程高手,就交给了他一个 小任务
利用已学过的数组知识,拓拓很快就解决了这个问题。他建立了五个数组,分别存储每个学生的各项信息。程序如下:
#include
using namespace std;
string name[101];
char sex[101];
int age[101];
float score[101],height[101];
int main()
{int n;cin >> n;for(int i=1;i<=n;i++){cin>>name[i]>>sex[i]>>age[i]>>score[i]>>height[i];}for(int i=n;i>=1;i--){cout<
Copy
但拓拓觉得这样写太麻烦了,而且一个人的信息保存在不同的数组中,调用时容易出现错误,且效率很低。这时,大佬提醒拓拓,可以用结构体来存储不同数据类型的信息。于是,他花了一点儿时间自学,很快将学生信息用结构体更清晰地表示了出来。
二、结构体的基本操作
1.结构体的声明
使用结构体前,需要先声明一个结构体类型,再进行定义和使用。结构体类型的声明格式为:
struct 结构体类型名{ //其中,sruct是关键字,在c++中表示结构体数据类型 成员变量1; //多个成员变量可以具有不同的数据类型数据类型 成员变量2;......
};
Copy
声明之后,就可以定义结构体变量了,格式如下:
结构体类型名 变量名;(struct 可省略)
Copy
例如
我们需要表示一个学生的信息,首先我们声明学生的结构体:
struct student{ //student表示结构体的类型名string name;char sex;int age;float height,score;
};
Copy
然后定义一个具体的学生:
student zhangsan;//声明一个student的结构体变量叫zhangsan
Copy
当然我们如果需要很多学生,可以声明为结构体数组:
student a[1001];//创建结构体数组a
//a数组中的每一个元素都是一个结构体类型student的变量
Copy
另外
为方便起见,我们一般直接在声明结构体的同时定义变量,格式如下:
struct 结构体类型名{ //其中,sruct是关键字,在c++中表示结构体数据类型成员变量1; //多个成员变量可以具有不同的数据类型数据类型成员变量2;......
}结构体变量表;
Copy
比如:
struct student{string name; char sex;int age; float height,score;
}a[1001];
Copy
2.结构体的使用
(1)将结构体变量视为一个整体进行操作,例如:
swap(a[1], a[2]);
Copy
(2)使用符号“.”对结构体变量的成员进行操作,“.”的含义可以理解为中文的“的”,格式为:
结构体名.成员变量名
Copy
比如:
student a;//李四cin >> a.name;//输入赋值李四的名字a.age = 23;//直接赋值给李四的年龄为23
Copy
3.结构体的初始化
(1)集合形式,比如:
student a = {"tuotuo",'F',12,168,100};
Copy
(2)逐一赋值,比如:
student a;
cin >> a.name >> a.sex;
a.age = 12;
Copy
三、结构体排序
1.sort()函数
在前面的学习中,我们已经接触了各种排序算法,比如选择排序、冒泡排序、插入排序、桶排序、sort()等。其中,sort()函数是使用起来篇幅最短的排序方式。
使用sort()的基本格式为:
sort(首元素地址,尾元素地址的下一项,比较函数);
Copy
在sort()函数的三个参数中,前两个是必填的,第三个 比较函数 可以没有,默认按照从小到大的顺序排序。一般来说,对于基本数据类型,如int、long long int 、double、float、char等,可以用两个参数的sort函数非常方便地实现递增排序,比如:
int a[6] = { 6,5,4,3,2,1};
sort(a,a+6);
for( int i=0; i<6; i++) cout<
Copy
其运行结果为:
1 2 3 4 5 6
Copy
2.一维数组的sort()函数
有时候题目要求从大到小排序,或者对结构体这样自定义类型进行排序,此时就要用到函数sort()的第三个参数 比较函数 。
首先我们定义一个bool类型的cmp()函数用于排序。只要在调用时将函数指针cmp写在sort函数的第三个参数的位置即可。
定义函数cmp()的示例如下:
bool cmp(int a, int b)
{ return a>b;
}
Copy
调用时,只需要写入第三个参数即可,注意不需要括号,如下:
int a[6] = {2,3,4,5,1,7};
sort(a, a+6, cmp);
for( int i=0; i<6; i++)cout<
Copy
其运行结果为:
7 5 4 3 2 1
Copy
3.结构体中的sort()函数
现在给你一个结构体,现在有这样一个要求:按照年龄从小到大输出。
那我们就照结构体中成员变量age(也就是年龄)进行从小到大的排序,代码如下:
struct student {string name; int age; float height;
}a[10];
bool cmp(student a, student b){ return a.age < b.age;
}
int main(){ ...//输出 sort(a, a + n, cmp);//按照年龄从小到大排序 ...//输出
}
Copy
四、例题
1.成绩排序
【题目描述】
输入N个学生的姓名、性别、和语文、数学的得分,按语文从高到低输出,语文一样的按数学成绩从高到低输出。性别用(female,male)表示。
【输入格式】
第1行,有一个整数N,N的范围是[1…100];
下面有N行,每行一个 姓名,性别,2个整数。2个整数分别代表该学生的语文和数学的得分。
姓名由不超过10个的小写字母组成,整数范围[1…100]
【输出格式】
总分排序后的名单,共N行,每行格式:姓名 性别 语文 数学 用空格隔开。
基本思路
输入,之后按照题目的要求排序,最后输出即可。
参考代码如下:
#include
using namespace std;struct student
{string xm;//姓名 string xb;//性别 int yw;//语文 int sx;//数学
};
student s[101];bool cmp(student s1, student s2)
{if(s1.yw != s2.yw)//语文不同,按照语文从高到低排序return s1.yw > s2.yw;else//语文相同,按照数学从高到低排序return s1.sx > s2.sx;
}int main()
{int n;cin>>n;for(int i=0;i>s[i].xm>>s[i].xb>>s[i].yw>>s[i].sx;}sort(s,s+n, cmp);//排序for(int i=0;i
Copy
2.特殊的成绩排序
【题目描述】
输入N个学生的姓名和语文、数学的得分,按总分从高到低输出。分数相同的按输入先后输出。
【输入格式】
第1行,有一个整数N,N的范围是[1…100];
下面有N行,每行一个 姓名,2个整数。2个整数分别代表该学生的语文和数学的得分。
姓名由不超过10个的小写字母组成,整数范围[1…100]
【输出格式】
总分排序后的名单,共N行,每行格式:姓名 语文 数学 总分,用空格隔开。
【输入样例】
4
qqq 10 10
www 10 20
eee 15 10
rrr 19 1
Copy
【输出样例】
www 10 20 30
eee 15 10 25
qqq 10 10 20
rrr 19 1 20
Copy
基本思路
和上一题类似,输入,排序,然后输出。
但是总分怎么办?输入先后顺序怎么处理?
遇到这种问题,可以在结构体定义的时候,添加相应的变量。
比如添加总分变量和顺序变量
struct stu
{string mz;//名字int yw;//语文 int sx;//数学 int zf;//总分 int id;//输入的序号
};
Copy
那这两个变量怎么放进来呢?可以 在输入的时候就放进来。
for(int i = 1; i <= n; i++)
{cin >> s[i].mz >> s[i].yw >> s[i].sx;s[i].zf = s[i].yw + s[i].sx;//输入的时候可以计算总分s[i].id = i;//把i当成序号记录一下
}
Copy
最后实现一下比较函数即可。
参考代码如下:
#include
using namespace std;
struct stu
{string mz;//名字int yw;//语文 int sx;//数学 int zf;//总分 int id;//输入的序号
};
bool cmp(stu s1, stu s2)//比较两个人的情况
{if(s1.zf != s2.zf)//总分不等,则按照总分从大到小排序return s1.zf > s2.zf;else//总分相等,按照输入顺序从小到大排序return s1.id < s2.id;
}
int main()
{stu s[101];//结构体数组sint n;cin >> n;for(int i = 1; i <= n; i++){cin >> s[i].mz >> s[i].yw >> s[i].sx;s[i].zf = s[i].yw + s[i].sx;//输入的时候可以计算总分s[i].id = i;//把i当成序号记录一下}sort(s+1, s+n+1, cmp);//结构体需要自定义比较方式 for(int i = 1; i <= n; i++)cout << s[i].mz << " " << s[i].yw << " " << s[i].sx << " " << s[i].zf << endl;
}
Copy
五、练习
成绩排序
高校录取
谁拿了最多奖学金
年龄排序
奖学金
植树积分
拓尔思学员合影
生日相同问题
颠倒排序
德才论
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
