数据结构 第一章 结构体

本文介绍了如何在C语言中使用结构体student处理包括姓名、性别、年级、地址等不同类型的数据,并展示了如何定义结构体、成员操作、变量初始化以及进行成员函数调用。实例涵盖学生信息输入输出、成绩统计、年龄排序和离散化基础,通过排序和自定义比较函数实现数据的有序排列。
摘要由CSDN通过智能技术生成

概述

        迄今为止,我们介绍了简单的数据类型:整形、实型、字符型以及数组定义的变量,其中数组中各元素都具有相同的类型。

        现在,我们要处理一个学生的数据: 包括姓名, 年级 ,  性别,    地址等不同的数据类型又该如何处理?

        在数据库中,我们通常要用“记录”来描述一个实体:如学生、教材、……

        在C语言中,允许程序员自定义类型,这就是结构:

      

一、结构体(struct)定义和操作

第一种定义方式:

    

第二种定义方式:

        也可以不定义结构类型,而直接定义结构变量。

       

定义了student类型,同时定义了student类型的三个变量stud1、stud2、stud3。注意分号的位置。

二、结构体变量的特点

(1)结构体变量可以整体操作,

         例如:      swap(a[j],a[j+1]);

(2)结构体变量的成员访问也很方便、清晰,

         例如:      cin>>a[i].name;

(3)结构体变量的初始化和数组的初始化类似,

         例如: student op={"gaoxiang",89,90,179};

三、成员调用

       结构体变量与各个成员之间引用的一般形式为:

       结构体变量名  .  成员名      

       对于上面定义的结构体变量,我们可以这样给成员赋值:       cin>>a[i].name;     不能写成cin>>a[i];     

       a[i].total=a[i].chinese+a[i].math;  //就像用整型变量一样      

        实际上结构体成员的操作与该成员类型所具有的操作是一致的。  

        成员运算符“.”在存取成员数值时使用,其优先级最高,并具有左结合性。

       在处理包含结构体的结构体时,可记作: strua.strub.membb 这说明结构体变量strua有结构体成员strub;结构体变量strub有成员membb。

四、成员函数调用

        结构体成员函数调用的一般形式为: 结构体变量名.成员函数 结构体成员函数默认将结构体变量作为引用参数。

五、例题

例1、学生信息

【问题描述】

输入一个学生的信息,包括姓名、性别、年龄、体重,再输出这些信息。

【输入格式】

一行,依次是学生的姓名、性别、年龄、体重。

【输出格式】

一行,依次是姓名、性别、年龄、体重(体重保留一位小数)。

【输入样例】

zhangsan m 20 90.5

【输出样例】

zhangsan m 20 90.5

#include<bits/stdc++.h>
using namespace std;
struct student{
     string name;
     char sex;
     int age;
     double weight;
};
int main(){
     student stu;
     cin >> stu.name >> stu.sex >> stu.age >> stu.weight;
     cout <<stu.name <<" "<< stu.sex <<" "<< stu.age <<" "<< stu.weight << endl;
     return 0;
}

例2、成绩统计。输入N个学生的姓名和语文、数学的得分,按总分从高到低输出。

输入格式:

第1行,有一个整数N,N的范围是[1…100];

下面有N行,每行一个姓名,2个整数。姓名由不超过10个的小写字母组成,整数范围是[0…100]。

输出格式:      

 总分排序后的名单,共N行,每行格式:姓名  语文  数学  总分。

输入样例:

4
gaoxiang 78 96
angxi 70 99
liujia 90 87
zhangjin 78 91

输出样例:    

liujia  90  87  177    

gaoxiang  78  96  174    

wangxi  70  99  169    

zhangjin  78  91  169

分析:由于姓名是字符串,分数是整数,如果用数组保存,则要两个数组,比如:     string name[100];     int score[100][3]; 这种方法不利于把一个学生的信息当成一个整体处理。

下面程序中通过使用结构(struct)类型的方法来解决这个问题。

#include<bits/stdc++.h>
using namespace std;
struct student
{	string name;
	int chinese,math;
	int total;
};                              //定义一个struct的类型,类型名叫:student
student a[110];                 //定义一个数组a,每个元素是student类型
int n;
int main()
{   cin>>n;
	for (int i=0; i<n; i++)     //对结构体中成员的赋值、取值。
	{   cin>>a[i].name;
	    cin>>a[i].chinese>>a[i].math;		
		a[i].total=a[i].chinese+a[i].math;
	}
	for (int i=0; i<n-1; i++)
	   for (int j=i+1; j<n; j++)      //冒泡排序
	       if (a[j].total<a[j+1].total) swap(a[j],a[j+1]);		 	 
	for (int i=0; i<n; i++)      //输出
	  cout<<a[i].name<<' '<<a[i].chinese<<' '<<a[i].math<<' '<<a[i].total<<endl;
	return 0;
}

用sort排序:

#include<bits/stdc++.h>
using namespace std;
struct student
{	string name;
	int chinese,math;
	int total;
};                              //定义一个struct的类型,类型名叫:student
student a[110];                 //定义一个数组a,每个元素是student类型

bool cmp(student a,student b)
{
	return a.total>b.total;
}

int n;
int main()
{   cin>>n;
	for (int i=0; i<n; i++)     //对结构体中成员的赋值、取值。
	{   cin>>a[i].name;
	    cin>>a[i].chinese>>a[i].math;		
		a[i].total=a[i].chinese+a[i].math;
	}
	sort(a,a+n,cmp);	 	 
	for (int i=0; i<n; i++)      //输出
	  cout<<a[i].name<<' '<<a[i].chinese<<' '<<a[i].math<<' '<<a[i].total<<endl;
	return 0;
}

例3、年龄排序

【问题描述】

输入 n 个学生的信息,包括姓名、性别、出生年月。要求按年龄从小到大依次输出这些学生的信息。数据保证没有学生同年同月出生。

【输入格式】

第一行一个整数 n,表示学生人数,n≤100。

接下来 n 行,每一行依次输入学生的姓名、性别、出生年份、出生月份。

【输出格式】

按年龄从小到大,一行输出一个学生的原始信息。

输入样例

5

John male 1999 12

David female 1999 8

Jason male 1998 11

Jack female 1998 8

Kitty female 2000 7

【输出样例】

Kitty female 2000 7

John male 1999 12

David female 1999 8

Jason male 1998 11

Jack female 1998 8

#include<bits/stdc++.h>
using namespace std;
struct stu
{
    string name;
    string sex;
    int year,month;
};
const int MAXN = 110;
stu a[MAXN];
int main()
{   int n;
    cin >> n;
    for(int i = 1; i <= n; i++)
          cin >> a[i].name >> a[i].sex >> a[i].year >> a[i].month;
    for(int i = 1; i <= n; i++)
          for(int j = i+1; j <= n; j++)
                if(a[i].year < a[j].year || a[i].year == a[j].year && a[i].month < a[j].month)
                       swap(a[i],a[j]);
    for(int i = 1; i <= n; i++){
          cout<< a[i].name <<" "<< a[i].sex <<" ";
          cout<< a[i].year <<" "<< a[i].month << endl;
    }
    return 0;
}

用sort排序:

#include<bits/stdc++.h>
using namespace std;
struct stu
{
    string name;
    string sex;
    int year,month;
};
const int MAXN = 110;
stu a[MAXN];
bool cmp(stu a,stu b)
{   return a.year > b.year || a.year == b.year && a.month > b.month;
}
int main()
{   int n;
    cin >> n;
    for(int i = 1; i <= n; i++)
          cin >> a[i].name >> a[i].sex >> a[i].year >> a[i].month;
    sort(a+1,a+n+1,cmp);
    for(int i = 1; i <= n; i++){
          cout<< a[i].name <<" "<< a[i].sex <<" ";
          cout<< a[i].year <<" "<< a[i].month << endl;
    }
    return 0;
}

例5、  离散化基础。

以后要学习使用的离散化方法编程中,通常要知道每个数排序后的编号(rank值)。

输入格式:    

第1行,一个整数N,范围在[1…10000];

第2行,有N个不相同的整数,每个数都是int范围的。

输出格式:    

依次输出每个数的排名。

输入样例:    

5

8 2 6 9 4

输出样例:    

4 1 3 5 2    

分析:

排序是必须的,关键是怎样把排名写回原来的数“下面”。程序使用了分别对数值和下标不同关键词2次排序的办法来解决这个问题,一个数据“节点”应该包含数值、排名、下标3个元素,用结构体比较好。

#include<bits/stdc++.h>
using namespace std;
struct node
{	int data;                   //数值
	int rank;                   //排名
	int index;                  //下标
};                              //定义struct类型
node a[10001];
int n;
bool comp1(node x,node y)
{	return x.data<y.data;}      //自定义比较函数 
bool comp2(node x,node y)
{	return x.index<y.index;}    //自定义比较函数 
int main()
{	cin>>n;
	for (int i=1; i<=n; i++) 
	   cin>>a[i].data,a[i].index=i;
	sort(a+1,a+1+n,comp1);       //根据值排序,求排名rank 
	for (int i=1; i<=n; i++) a[i].rank=i;
	sort(a+1,a+1+n,comp2);       //根据下标排序,回到原数据次序 
	for (int i=1; i<=n; i++)
	     cout<<a[i].rank<<' ';
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值