派生类数据类型与结构体本章主要介绍派生类数据类课件_第1页
派生类数据类型与结构体本章主要介绍派生类数据类课件_第2页
派生类数据类型与结构体本章主要介绍派生类数据类课件_第3页
派生类数据类型与结构体本章主要介绍派生类数据类课件_第4页
派生类数据类型与结构体本章主要介绍派生类数据类课件_第5页
已阅读5页,还剩123页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第九章派生类数据类型与结构体本章主要介绍派生类数据类型和结构体,这部分是FORTRAN90以上版本新增加的内容,它使FORTRAN语言功能得到进一步的加强,使用更加方便。9.1派生类数据类型FORTRAN90以前的FORTRAN版本,没有用户自定义的数据类型。这样给用户带来的不便,例如,我们要比较完整的表达多个学生的信息,假设学生包含的信息有:学生所在院系、学生班级、姓名、学号、年龄、性别、家庭住址、各科考试成绩等等,同时要对这些数据进行相应的处理,如查找、插入、删除、计算、排序等。以前FORTRAN所用的方法是:将学生的每一项放在一个数组中,如:所有学生的姓名可以放在一个字符数组中,学号可以存放在一个整型数组中,成绩可以存放在一个实型数组中等等,这样,要解决这个问题,需要对多个不同数组进行处理,编写程序必须注意各个学生所对应的数据项在数组中不能错位,否则将会张冠李戴。第九章派生类数据类型与结构体1FORTRAN90在这方面有较大的改进,主要是允许字定义派生类数据类型(简称派生类型),有了它,就能较容易地描述上述问题。派生数据类型定义的一般格式为:TYPE[,ACCESS[::]]派生类名字分量表ENDTYPE派生类名FORTRAN90在这方面有较大的改进,主要是允许字定义派生2说明1.TYPE为关键字,是每定义一个派生类型的起点。2.ACCESS是可供选择的访问方式说明,分PRIVATE(私有的)和PUBLIC(公共的)两种,例如:REAL,PRIVATE::X1,X2该语句定义了两个实型的私有派生类变量X1、X2。注意声明为PRIVATE时,外部模块不能访问它;声明为PUBLIC属性的实体,在其程序单位中用了USE语句就可以使用;默认方式为公共访问方式。“::”为作用域符。

说明1.TYPE为关键字,是每定义一个派生类型的起点。33.派生类名为一个标识符,用户可以用任意标示符命名。4.分量表可以是各种类型的数据,并且可以是多项,每项前面必须加上类型说明。5.ENDTYPE派生类名为派生类定义结束的标志。3.派生类名为一个标识符,用户可以用任意标示符命名。4

下面看一个具体实例:TYPESTUDENTCHARACTER(15)NAMEINTEGERNUMLOGICALSEXCHARACTER(30)ADDRESSENDTYPE下面看一个具体实例:5其中STUDENT为派生类名。该派生类包含一个最多可存放15个字符的字符数组NAME、一个整型的变量NUM、一个逻辑类型变量SEX、一个最多可存放30个字符的字符数组ADDRESS,由于该派生类访问方式已经省略,因此,按照默认访问方式:公共访问方式对其进行访问。

其中STUDENT为派生类名。该派生类包含一个最多可存放1569.2结构体的定义与引用

有时我们需要将不同类型的数据结合成一个统一的整体,以便于引用。本节介绍派生类型中一种较简单的数据类型:结构体,它是由若干个相互之间有联系的数据项构成的。9.2结构体的定义与引用有时我们需要将不同类型的数据结合7结构体类型定义的一般形式为:TYPE(派生类型名)::结构体名。例如第一节,定义学生派生类后,就可以用它来定义结构体变量TYPE(STUDENT)::S1,S2

该语句定义了两个结构体变量S1和S2,它们都包含STUDENT的所有成员:NAME、NUM、SEX、ADDRESS等5项。

9.2.1结构体类型定义结构体类型定义的一般形式为:9.2.1结构体类型定义8结构体既可以在程序中定义,也可以和其他内部数据类型一样放在另一个派生类型的定义中定义,即所谓嵌套定义。例如TYPESTUDENTRECORDCHARACTER(15)NAMEINTEGERNUMLOGICALSEXCHARACTER(30)ADDRESSENDTYPE结构体既可以在程序中定义,也可以和其他内部数据类型一样放在另9TYPESTUDENTTOGETHERTYPE(STUDENTRECORD)::STUDENTREALMATHREAL ENGLISHREAL CHINESEENDTYPE其中,先定义STUDENTRECORD结构体,再把TYPE(STUDENTRECORD)::STUDENT语句放在结构体定义语句TYPESTUDENTTOGETHER之内,这样构成嵌套定义,即用一个结构体作为另外一个结构体的成员。

TYPESTUDENTTOGETHER10这时,如果定义如下结构体:TYPE(STUDENTTOGETHER)::S这样,结构体变量S包含:三个实型变量MATH、ENGLISH、CHINESE和一个结构体变量STUDENT,而STUDENT又包含NAME、NUM、SEX、ADDRESS四个成员。

这时,如果定义如下结构体:11

9.2.2结构体成员的引用

结构体成员的引用有两种方式:1.结构体名%成员表2.结构体名.成员表例如对上面定义个S1,S2两个结构体变量,成员的引用如下:S1.NAME、S1.NUM、S1.SEX、S1.ADDRESSS2%NAME、S2%NUM、S2%SEX、S2%ADDRESS。

9.2.2结构体成员的引用

结构体成员的引用有两种方式:12注意:(1)两种引用方式可以交叉使用,但为了清晰起见,在一个程序中最好使用一种。(2)在含嵌套定义的结构体中,成员引用应当嵌套使用“%”或“.”,例如,对上面结构体S中成员NUM的引用方式为S%STUDENT%NUM。注意:(1)两种引用方式可以交叉使用,但为了清晰起见,在一个13

9.3结构体的初始化

9.3.1利用赋值语句给结构体成员赋值下面看一个完整的例子:例9.1某单位职工工资表包含的记录有:姓名、性别、家庭住址、工资等项,现计算三个职工工资的平均值。程序如下:

9.3结构体的初始化

9.3.1利用赋值语句给结构体成员14 TYPECLERK CHARACTER(15)NAME LOGICALSEX CHARACTER(30)ADDRESS INTEGERSAL ENDTYPE TYPE(CLERK)::S1,S2,S3 S1.SAL=800 S2%SAL=900 S3.SAL=700 AVER=(S1%SAL+S2.SAL+S3.SAL)/3 PRINT*,"三个职工的平均工资为:",AVER END TYPECLERK15其中结构体成员赋值的三个语句为:S1.SAL=800、S2%SAL=900、S3.SAL=700,这与普通变量赋值本质上是一样的,也就是说可以把某结构体变量成员的引用一起当作一个变量来使用,因此也可以用输入语句来赋值。

其中结构体成员赋值的三个语句为:S1.SAL=800、16例9.2学生记录包含如下数据项:姓名、一门功课的成绩、性别、家庭住址,要求打印学生各数据项,并求出该门成绩的平均值。程序如下: TYPESTUDENT CHARACTER(15)NAME INTEGERGRADE LOGICALSEX CHARACTER(30)ADDRESS ENDTYPE TYPE(STUDENT)::S1,S2,S3例9.2学生记录包含如下数据项:姓名、一门功课的成绩、性别17

PRINT*,"请输入三个学生的名字" READ*,S1.NAME,S2.NAME,S3.NAME PRINT*,"请输入三个学生的成绩" READ*,S1.GRADE,S2.GRADE,S3.GRADE PRINT*,"请输入三个学生的性别" READ*,S1%SEX,S2%SEX,S3%SEX PRINT*,"请输入三个学生的住址" READ*,S1.ADDRESS,S2.ADDRESS,S3.ADDRESS PRINT*,"三个学生的名字为",S1.NAME,S2.NAME,S3.NAME PRINT*,"请输入三个学生的名字"18

PRINT*,"三个学生的性别为",S1%SEX,S2%SEX,S3%SEX PRINT*,"三个学生的住址为",S1.ADDRESS,S2.ADDRESS,$S3.ADDRESS AVER=(S1%GRADE+S2.GRADE+S3.GRADE)/3 PRINT*,"三个学生的平均成绩为:",AVER END PRINT*,"三个学生的性别为",S1%SEX,S219请输入三个学生的名字输入:ZHANGLIWANG回车请输入三个学生的成绩输入三个正整数如859080回车请输入三个学生的性别输入.F..T..F.回车请输入三个学生的住址输入:CHANGSHAGUANGZHOUBEIJING回车请输入三个学生的名字20

最后输出结果为三个学生的名字为 ZHANG LI WANG三个学生的性别为 F T F三个学生的住址为 CHANGSHA GUANGZHOU BEIJING三个学生的平均成绩为 85最后输出结果为219.3.2定义的同时赋值

在定义结构体变量的同时,给定结构体各成员的值。其格式为:TYPE(派生数据类名)::结构体变量名=派生数据类名(成员初值表)其中,=后面的派生类名即为TYPE后面的派生类名;成员之间的值用“,”隔开。例如结构体如下:

9.3.2定义的同时赋值在定义结构体变量的同时,给定结构22 TYPETEACHER CHARACTER(12)NAME LOGICALSEX CHARACTER(15)POSITCHARACTER(30)ADDRESS INTEGERSALENDTYPE这样我们可以用如下方式给对应的结构体变量赋值:TYPE(TEACHER)::S1=TEACHER("ZHANG",.TRUE.,"PROFESSOR",”CHANGSHANG”,2000),S2,S3这样,结构体变量S1的值全部被给定。

TYPETEACHER23这种赋值方式应当注意:

(1)赋值时,所给的值类型和个数应与结构体变量定义中各成员的类型与个数保持一致。(2)可以将一个结构体变量的值直接赋给另外一个结构体变量,

这种赋值方式应当注意:(1)赋值时,所给的值类型和个数应与24INTEGERS TYPESTUDENTRECORD CHARACTER(15)NAME INTEGERNUM LOGICALSEX CHARACTER(30)ADDRESS ENDTYPE TYPE(STUDENTRECORD)::S1,S2 S1=STUDENTRECORD("ABCD",20,.TRUE.,"CHANGSHA") S2=S1 S=S2%NUM+S1%NUM PRINT*,S ENDINTEGERS25这里,通过S2=S1语句,使S1和S2两个结构体变量得到相同的值,输出S的结果为40。当结构体中包含成员较多时,可以用嵌套定义的方式,使结构体变得简洁,如例9.2中,当学生的成绩是多门时,可以将它们单独定义在一个结构体中,然后将该结构体包含到主结构体中,下面再看一个例子:

这里,通过S2=S1语句,使S1和S2两个结构体变量得到相同26例9.3、学生信息包含如下数据项:姓名、性别、学号、年龄和5门功课的成绩:语文、数学、物理、化学、英语,要求输入三个学生的记录,打印出相关信息与总成绩。分析:学生的成绩有5门,可以将它们放在一个名为STUDENTSCORE的结构体中,而将学生所有记录存放在名为STUDENTRECORD的结构体中,该结构体包含结构体STUDENTSCORE,然后作相应处理,注意学生成绩输入语句。程序如下:

例9.3、学生信息包含如下数据项:姓名、性别、学号、年龄和527PROGRAMXUESHENGJILU REALAVER1,AVER2,AVER3TYPESTUDENTSCORE REALCHINESE REALMATH REALPHYSICS REALCHEMISTRY REALENGLISH ENDTYPEPROGRAMXUESHENGJILU28TYPESTUDENTRECORD CHARACTER(17)NAME LOGICALSEX INTEGERNUMBER INTEGERBIRTHDAY TYPE(STUDENTSCORE)::SCORE ENDTYPE TYPE(STUDENTRECORD)::S1,S2,S3 PRINT*,"请输入3个学生的姓名" READ*,S1.NAME,S2.NAME,S3.NAME PRINT*,"请输入3个学生的性别" READ*,S1.SEX,S2.SEX,S3.SEX PRINT*,"请输入3个学生的学号" READ*,S1.NUMBER,S2.NUMBER,S3.NUMBER PRINT*,"请输入3个学生的年龄" READ*,S1.BIRTHDAY,S2.BIRTHDAY,S3.BIRTHDAYTYPESTUDENTRECORD29PRINT*,"请输入3个学生的语文成绩" READ*,S1%SCORE%CHINESE,S2%SCORE%CHINESE,S3%SCORE%CHINESE PRINT*,"请输入3个学生的数学成绩" READ*,S1%SCORE%MATH,S2%SCORE%MATH,S3%SCORE%MATH PRINT*,"请输入3个学生的物理成绩" READ*,S1%SCORE%PHYSICS,S2%SCORE%PHYSICS,S3%SCORE%PHYSICS PRINT*,"请输入3个学生的化学成绩" READ*,S1%SCORE%CHEMISTRY,S2%SCORE%CHEMISTRY,S3%SCORE%CHEMISTRY PRINT*,"请输入3个学生的英语成绩" READ*,S1%SCORE%ENGLISH,S2%SCORE%ENGLISH,S3%SCORE%ENGLISH AVER1=(S1%SCORE%CHINESE+S1%SCORE%MATH+S1%SCORE%PHYSICS+S1%SCORE%CHEMISTRY+S1%SCORE%ENGLISH)/5.0PRINT*,"请输入3个学生的语文成绩"30

AVER2=(S2%SCORE%CHINESE+S2%SCORE%MATH+S2%SCORE%PHYSICS+S2%SCORE%CHEMISTRY+S2%SCORE%ENGLISH)/5.0 AVER3=(S3%SCORE%CHINESE+S3%SCORE%MATH+S3%SCORE%PHYSICS+S3%SCORE%CHEMISTRY+S3%SCORE%ENGLISH)/5.0 PRINT*,S1.NAME,S1.SEX,S1.NUMBER,S1.BIRTHDAY PRINT*,S1%SCORE%CHINESE,S1%SCORE%MATH,S1%SCORE%PHYSICS,$S1%SCORE%CHEMISTRY,S1%SCORE%ENGLISH,AVER1 AVER2=(S2%SCORE%CHINESE+S231PRINT*,S2.NAME,S2.SEX,S2.NUMBER,S2.BIRTHDAY PRINT*,S2%SCORE%CHINESE,S2%SCORE%MATH,S2%SCORE%PHYSICS,$S2%SCORE%CHEMISTRY,S2%SCORE%ENGLISH,AVER2 PRINT*,S3.NAME,S3.SEX,S3.NUMBER,S3.BIRTHDAY PRINT*,S3%SCORE%CHINESE,S3%SCORE%MATH,S3%SCORE%PHYSICS,$S3%SCORE%CHEMISTRY,S3%SCORE%ENGLISH,AVER3 ENDPRINT*,S2.NAME,S2.SEX,S2.NUMBE329.5综合实例

在这一节中,我们结合数据处理中的一些常见操作,如数据的排序、插入、查找、删除、更新等,介绍结构体的综合应用实例。为了简便起见,我们同样以学生信息为例,且假设学生信息仅仅包含姓名和一门功课的成绩,另外加一个唯一的标识(如学号),现在考虑如何完成上述的操作。首先定义学生结构体如下:

9.5综合实例在这一节中,我们结合数据处理中的一些常见33TYPESTUDENTRECORDCHARACTER(15) NAMEINTEGER MARKINTEGER GRADEENDTYPESTUDENTRECORD其中:NAME代表学生姓名,MARK代表标示,GRADE代表成绩

TYPESTUDENTRECORD34其次必须考虑的是如何存储学生信息的问题。为此,定义如下结构体数组:TYPE(STUDENTRECORD),DIMENSION(STNUM)::STRECORD其中,STNUM为符号常量,代表学生人数,可以在使用之前通过INTEGER,PARAMETER::STNUM=20来定义,该语句的含义为定义一个整型的符号常量STNUM,其值为20,可以根据学生人数修改其值,下面一步一步地介绍完成上述的操作。

其次必须考虑的是如何存储学生信息的问题。359.5.1排序

排序(SORTING)是数据处理领域中最常用的一种运算,分为升序和降序排序两种,排序方法较多,常见的有简单交换排序、选择排序、冒泡排序、堆排序、快速排序、归并排序等,不同的排序方法,有不同的优点和缺点,但其中某些排序牵涉到数据结构方面的知识,如堆排序,已超出本书范围,读者如果有兴趣,可以参看有关数据结构方面的知识,这里仅仅使用简单交换法排序。排序的主要目的之一是为了查找方便,因此一般牵涉到排序字或称关键词(KEY)问题,这里用每个学生的标识MARK作为关键字进行排序字,如果要对学生的成绩排序,只须将MARK改为GRADE即可。

9.5.1排序排序(SORTING)是数据处理领域中最常36简单交换法思想介绍如下:先将除第一个数据项以外的所有数据与第一个数据项比较,前者小,则将与它有关的记录与后者有关的记录交换,显然,第一轮排序进行完毕,排序项最小者将被交换到最前面。然后从第二个排序项开始重复前述操作,依次类推,直到排序完成止。我们定义SORT函数来完成排序操作,程序如下:简单交换法思想介绍如下:37

SUBROUTINESORT(STRECORD,N) TYPESTUDENTRECORDCHARACTER(15) NAME INTEGER MARK INTEGER GRADE ENDTYPESTUDENTRECORD INTEGER,PARAMETER::STNUM=5 TYPE(STUDENTRECORD),DIMENSION(STNUM)::STRECORD TYPE(STUDENTRECORD)::TEMP INTEGERI,J,NSUBROUTINESORT(STRECORD,N)38 DO I=1,N DO J=I+1,N IF(STRECORD(I)%MARK>STRECORD(J)%MARK)THEN TEMP=STRECORD(I) STRECORD(I)=STRECORD(J) STRECORD(J)=TEMP ENDIFENDDOENDDOEND

DO I=1,N399.5.2查找

查找(SEARCH)同人们日常生活有着密切的联系。如从字典中查找单词,从工资表中查找工资,从电话号码薄中查找电话,从图书馆中查找书,从地图上查找路线和地址等。同排序一样,查找的方法非常多,如顺序查找、二分查找、索引查找、分块查找、B_树查找等,这里介绍无序情况下的顺序查找和有序情况下的二分查找两种。

9.5.2查找查找(SEARCH)同人们日常生活有着密40

一、顺序查找

顺序查找的基本思想是:先输入待查找的标示KEY,从第一个开始,将它与已经存放好的学生记录中相应的项(在这里用MARK)比较,如果KEY与MARK相同,说明已找到,这时可以输出相关信息,如果KEY与MARK不同,则拿下一个记录中的MARK与KEY比较,直到找到或者到最后一个记录止,并输出相关的信息。程序如下:

一、顺序查找

顺序查找的基本思想是:先输入待查找的标示KE41SUBROUTINESORT_SEARCH(STRECORD,N,KEY) TYPESTUDENTRECORD CHARACTER(15)NAME INTEGERMARK INTEGER GRADE ENDTYPESTUDENTRECORD INTEGER,PARAMETER::STNUM=5 TYPE(STUDENTRECORD),DIMENSION(STNUM)::STRECORD INTEGERI,N,KEYSUBROUTINESORT_SEARCH(STRECOR42

I=1 DOWHILE((STRECORD(I)%MARK.NE.KEY).AND.(I.LE.N)) I=I+1ENDDO IF(I<=N)THEN PRINT*,"学生已经找到,其他相关的信息为:" PRINT*,"姓名为:",STRECORD(I)%NAME PRINT*,"成绩为:",STRECORD(I)%GRADE ELSE PRINT*,"查无此人" ENDIF END

I=1432.二分查找

二分查找,又称折半查找。作为二分查找对象的表必须是有序表,其最大的优点是查找速度非常快,数据越多,效果越明显。其基本思想如下:定义一个TOP指针(在这里可以理解为数组的第一个下标)指向表的第一个元素,定义一个BOT指针,指向表的最后一个元素,一个MID指针指向表的中间元素(靠左),即MID=(TOP+BOT)/2取下限,每一次查找,总是将待查项与MID指针所对应的元素的对应项比较,如果对应项刚好就是要查找的项,则说明已经找到,可以输出相关的信息;如果对应项小于待查项,则改BOT=MID-1,重新计算MID,然后重复前面的比较;如果对应项大于待查项,则改TOP=MID+1,重新计算MID,然后重复前面的比较。这样如果到TOP大于BOT还没有找到对应待查项,说明该项不在此表中。程序如下:

2.二分查找二分查找,又称折半查找。作为二分查找对象的表必44SUBROUTINEHALF_SEARCH(STRECORD,TOP,BOT,KEY) TYPESTUDENTRECORD CHARACTER(15)NAME INTEGERMARK INTEGER GRADE ENDTYPESTUDENTRECORD INTEGER,PARAMETER::STNUM=5 TYPE(STUDENTRECORD),DIMENSION(STNUM)::STRECORD

SUBROUTINEHALF_SEARCH(STRECOR45 INTEGERTOP,BOT,MID,KEY MID=(TOP+BOT)/2 DO100WHILE((STRECORD(MID)%MARK.NE.KEY).AND.(TOP.LE.BOT)) IF(STRECORD(MID)%MARK<KEY)THEN TOP=MID+1 ELSE BOT=MID-1 ENDIF MID=(TOP+BOT)/2 INTEGERTOP,BOT,MID,KEY46100 CONTINUE

IF(TOP<=BOT)THEN

PRINT*,"学生已经找到,其他相关的信息为:"

PRINT*,"姓名为:",STRECORD(MID)%NAME

PRINT*,"成绩为:",STRECORD(MID)%GRADE

ELSE

PRINT*,"查无此人"

ENDIF

END

100 CONTINUE

IF(TOP<=BOT)THE479.5.3插入

插入是在原有信息的基础上加入一个新的记录,一般而言,分为表头插入,表尾插入和有序插入,这里主要介绍有序插入。所谓有序插入在根据关键字排好序的有序表中,插入一个新的记录,方法如下:先查找位置,将新记录的关键字与有序表中关键字比较,如果新记录的关键字小于当前比较的关键字,则拿下一个记录的关键字与新记录比较,直到表中记录的关键字大于新记录止,这时说明新记录应当插入该记录的前面。

9.5.3插入插入是在原有信息的基础上加入一个新的记录,48然后是表中记录的移动,这时,先应从当前表中最后一个记录开始到关键字刚好大于新记录的所有项依次后移。最后将新记录的置于查找到的位置即完成插入操作。为了理解该算法,下面用一个具体实例来对其进行说明。假设某有序表关键字依次如下:1 3 5 7 8 10 12 16新插入的记录关键字为4,则插入过程示意图如下:然后是表中记录的移动,这时,先应从当前表中最后一个记录开始到49

关键字为4的新记录插入位置1 3 5 7 8 10 12 16关键字为4的新记录插入位置1 3 5 7 8 10 12 50元素后移动以后结果:1 3 5 5 7 8 10 12 16其中第一个5所在的记录在将被新记录覆盖。插入新记录后,按关键字显示的结果为1 3 4 5 7 8 10 12 16

元素后移动以后结果:51程序如下:SUBROUTINESORT_INSERT(STRECORD,NEW,N)TYPESTUDENTRECORDCHARACTER(15)NAMEINTEGER MARKINTEGER GRADEENDTYPESTUDENTRECORD INTEGER,PARAMETER::STNUM=5程序如下:52 TYPE(STUDENTRECORD),DIMENSION(STNUM+1)::STRECORD TYPE(STUDENTRECORD)::NEW INTEGERI,N,JI=1 DO WHILE((STRECORD(I)%MARK.LT.NEW%MARK).AND.(I.LE.N-1)) I=I+1ENDDO DOJ=N-1,I,-1 STRECORD(J+1)=STRECORD(J) ENDDOSTRECORD(I)=NEW END

TYPE(STUDENTRECORD),DIMENS539.5.4删除

删除操作也是数据处理中常见的操作之一,要完成删除操作,第一步根据给定的信息(一般为关键字)查找相关的记录,然后删除。删除有两种方式,第一种是将待删除的记录所在的存储单元置空;第二种是将后面内容覆盖前面内容,下面要介绍的是第二种。设待删项为DEKEY,删除函数名为DEL,程序如下:

9.5.4删除删除操作也是数据处理中常见的操作之一,要完54 SUBROUTINEDEL(STRECORD,DEKEY,N) TYPESTUDENTRECORDCHARACTER(15)NAME INTEGERMARK INTEGER GRADE ENDTYPESTUDENTRECORD INTEGER,PARAMETER::STNUM=5 TYPE(STUDENTRECORD),DIMENSION(STNUM)::STRECORD TYPE(STUDENTRECORD)::TEMP INTEGERI,N,J,DEKEY SUBROUTINEDEL(STRECORD,DEKEY55N=STNUMI=1 DO100WHILE((STRECORD(I)%MARK.NE.DEKEY).AND.(I.LE.N))I=I+1ENDDO IF(I.GT.N)THEN PRINT*,"学生记录没找到,无法删除!" ELSETEMP=STRECORD(I)DOJ=I,NSTRECORD(J)=STRECORD(J+1)ENDDO PRINT*,"删除的记录为:",TEMP%NAME,TEMP%MARK,TEMP%GRADEENDIFEND其中,TEMP为一个临时记录,用于存放待删记录。N=STNUM569.5.6主程序

前面以给出了学生记录的一些基本操作函数,下面给出其主函数,读者可以将它与前面的函数结合起来一起使用。PROGRAMSTUDENT_RECORDSTYPESTUDENTRECORDCHARACTER(15)NAMEINTEGERMARKINTEGER GRADEENDTYPESTUDENTRECORDINTEGER,PARAMETER::STNUM=109.5.6主程序前面以给出了学生记录的一些基本操作函数,57!定义一个符号常量STNUM=10,用来代表要处理的学生数TYPE(STUDENTRECORD),DIMENSION(STNUM+1)::STRECORDTYPE(STUDENTRECORD)::NEW1…EXTERNALSORT,SORT_SEARCH,HALF_SEARCH,SORT_INSERT,DEL!调用函数的说明语句PRINT*,"请输入学生有关的信息"DOI=1,STNUMREAD*,STRECORD(I)%NAME,STRECORD(I)%MARK,STRECORD(I)%GRADEENDDO!定义一个符号常量STNUM=10,用来代表要处理的学生数58PRINT*,"请输入待处理的学生有关的信息"READ*,……CALL……!调用函数的语句,其函数个数可以根据需要增减PRINT*,“处理后学生所有信息如下:”DOI=1,STNUMPRINT*,STRECORD(I)%NAME,STRECORD(I)%MARK,STRECORD(I)%GRADEENDDOPRINT*,…ENDPRINT*,"请输入待处理的学生有关的信息"59主函数说明如下:首先定义学生信息结构体,其成员为学生姓名(NAME)、标示(MARK)、和一门成绩(GRADE),大家可以根据自己需要增加其他项。然后输入记录信息,及待处理的内容明,如待查学生的关键字,待插学生的记录等,它们就是后面各处理函数的实际参数,再根据处理的需要调用不同的函数,最后输出相关的信息。

主函数说明如下:60习

1、

写出下列程序的结果(1) TYPETEACHER CHARACTER(12)NAME LOGICALSEX CHARACTER(15)POSITCHARACTER(30)ADDRESS INTEGERSALENDTYPE TYPE(TEACHER)::S1,S2,S3 S1.SAL=800 S2%SAL=900 S3.SAL=700习题1、

写出下列程序的结果61 READ*,S1.SAL,S2.SAL,S3.SAL AVER=(S1%SAL+S2.SAL+S3.SAL)/3 PRINT*,"aver=",AVER END输入300400500输出结果为:(2) TYPESTUDENTRECORD CHARACTER(15) NAME INTEGER MARK INTEGER GRADE ENDTYPESTUDENTRECORD INTEGER,PARAMETER::STNUM=5 TYPE(STUDENTRECORD),DIMENSION(STNUM)::STRECORD TYPE(STUDENTRECORD)::TEMP INTEGERI,J

DO I=1,STNUM READ*,STRECORD(I)%NAME,STRECORD(I)%MARK,STRECORD(I)%GRADE ENDDO READ*,S1.SAL,S2.SAL,S3.SAL62

DO I=1,STNUM DO J=I+1,STNUM IF(STRECORD(I)%MARK>STRECORD(J)%MARK)THEN TEMP=STRECORD(I) STRECORD(I)=STRECORD(J) STRECORD(J)=TEMP ENDIF ENDDO ENDDO DO I=1,STNUM PRINT*,STRECORD(I)%NAME,STRECORD(I)%MARK,STRECORD(I)%GRADE ENDDO END当输入zhang 5 89li 3 65 DO I=1,STNUM63zhao 4 69liu 1 94hu 2 77时,输出:2、定义一个结构体变量,其成员包括学生的:学号、性别、年龄、专业、住址、电话号码等。3、用两种不同的方法为上面结构体变量赋值。4、定义结构体数组,结构体成员同第一题,为它赋值并输出。

5、在第第三题的基础上,以学号作关键字,完成查找更新等操作。6、已知职工工资表记录包括:职工号、姓名、年龄、职称、工资,建立一个10个职工组成的记录表,并找出职工中工资最高和最低者及相关信息,统计工资总额,计算职工平均工资。zhao 4 6964第九章派生类数据类型与结构体本章主要介绍派生类数据类型和结构体,这部分是FORTRAN90以上版本新增加的内容,它使FORTRAN语言功能得到进一步的加强,使用更加方便。9.1派生类数据类型FORTRAN90以前的FORTRAN版本,没有用户自定义的数据类型。这样给用户带来的不便,例如,我们要比较完整的表达多个学生的信息,假设学生包含的信息有:学生所在院系、学生班级、姓名、学号、年龄、性别、家庭住址、各科考试成绩等等,同时要对这些数据进行相应的处理,如查找、插入、删除、计算、排序等。以前FORTRAN所用的方法是:将学生的每一项放在一个数组中,如:所有学生的姓名可以放在一个字符数组中,学号可以存放在一个整型数组中,成绩可以存放在一个实型数组中等等,这样,要解决这个问题,需要对多个不同数组进行处理,编写程序必须注意各个学生所对应的数据项在数组中不能错位,否则将会张冠李戴。第九章派生类数据类型与结构体65FORTRAN90在这方面有较大的改进,主要是允许字定义派生类数据类型(简称派生类型),有了它,就能较容易地描述上述问题。派生数据类型定义的一般格式为:TYPE[,ACCESS[::]]派生类名字分量表ENDTYPE派生类名FORTRAN90在这方面有较大的改进,主要是允许字定义派生66说明1.TYPE为关键字,是每定义一个派生类型的起点。2.ACCESS是可供选择的访问方式说明,分PRIVATE(私有的)和PUBLIC(公共的)两种,例如:REAL,PRIVATE::X1,X2该语句定义了两个实型的私有派生类变量X1、X2。注意声明为PRIVATE时,外部模块不能访问它;声明为PUBLIC属性的实体,在其程序单位中用了USE语句就可以使用;默认方式为公共访问方式。“::”为作用域符。

说明1.TYPE为关键字,是每定义一个派生类型的起点。673.派生类名为一个标识符,用户可以用任意标示符命名。4.分量表可以是各种类型的数据,并且可以是多项,每项前面必须加上类型说明。5.ENDTYPE派生类名为派生类定义结束的标志。3.派生类名为一个标识符,用户可以用任意标示符命名。68

下面看一个具体实例:TYPESTUDENTCHARACTER(15)NAMEINTEGERNUMLOGICALSEXCHARACTER(30)ADDRESSENDTYPE下面看一个具体实例:69其中STUDENT为派生类名。该派生类包含一个最多可存放15个字符的字符数组NAME、一个整型的变量NUM、一个逻辑类型变量SEX、一个最多可存放30个字符的字符数组ADDRESS,由于该派生类访问方式已经省略,因此,按照默认访问方式:公共访问方式对其进行访问。

其中STUDENT为派生类名。该派生类包含一个最多可存放15709.2结构体的定义与引用

有时我们需要将不同类型的数据结合成一个统一的整体,以便于引用。本节介绍派生类型中一种较简单的数据类型:结构体,它是由若干个相互之间有联系的数据项构成的。9.2结构体的定义与引用有时我们需要将不同类型的数据结合71结构体类型定义的一般形式为:TYPE(派生类型名)::结构体名。例如第一节,定义学生派生类后,就可以用它来定义结构体变量TYPE(STUDENT)::S1,S2

该语句定义了两个结构体变量S1和S2,它们都包含STUDENT的所有成员:NAME、NUM、SEX、ADDRESS等5项。

9.2.1结构体类型定义结构体类型定义的一般形式为:9.2.1结构体类型定义72结构体既可以在程序中定义,也可以和其他内部数据类型一样放在另一个派生类型的定义中定义,即所谓嵌套定义。例如TYPESTUDENTRECORDCHARACTER(15)NAMEINTEGERNUMLOGICALSEXCHARACTER(30)ADDRESSENDTYPE结构体既可以在程序中定义,也可以和其他内部数据类型一样放在另73TYPESTUDENTTOGETHERTYPE(STUDENTRECORD)::STUDENTREALMATHREAL ENGLISHREAL CHINESEENDTYPE其中,先定义STUDENTRECORD结构体,再把TYPE(STUDENTRECORD)::STUDENT语句放在结构体定义语句TYPESTUDENTTOGETHER之内,这样构成嵌套定义,即用一个结构体作为另外一个结构体的成员。

TYPESTUDENTTOGETHER74这时,如果定义如下结构体:TYPE(STUDENTTOGETHER)::S这样,结构体变量S包含:三个实型变量MATH、ENGLISH、CHINESE和一个结构体变量STUDENT,而STUDENT又包含NAME、NUM、SEX、ADDRESS四个成员。

这时,如果定义如下结构体:75

9.2.2结构体成员的引用

结构体成员的引用有两种方式:1.结构体名%成员表2.结构体名.成员表例如对上面定义个S1,S2两个结构体变量,成员的引用如下:S1.NAME、S1.NUM、S1.SEX、S1.ADDRESSS2%NAME、S2%NUM、S2%SEX、S2%ADDRESS。

9.2.2结构体成员的引用

结构体成员的引用有两种方式:76注意:(1)两种引用方式可以交叉使用,但为了清晰起见,在一个程序中最好使用一种。(2)在含嵌套定义的结构体中,成员引用应当嵌套使用“%”或“.”,例如,对上面结构体S中成员NUM的引用方式为S%STUDENT%NUM。注意:(1)两种引用方式可以交叉使用,但为了清晰起见,在一个77

9.3结构体的初始化

9.3.1利用赋值语句给结构体成员赋值下面看一个完整的例子:例9.1某单位职工工资表包含的记录有:姓名、性别、家庭住址、工资等项,现计算三个职工工资的平均值。程序如下:

9.3结构体的初始化

9.3.1利用赋值语句给结构体成员78 TYPECLERK CHARACTER(15)NAME LOGICALSEX CHARACTER(30)ADDRESS INTEGERSAL ENDTYPE TYPE(CLERK)::S1,S2,S3 S1.SAL=800 S2%SAL=900 S3.SAL=700 AVER=(S1%SAL+S2.SAL+S3.SAL)/3 PRINT*,"三个职工的平均工资为:",AVER END TYPECLERK79其中结构体成员赋值的三个语句为:S1.SAL=800、S2%SAL=900、S3.SAL=700,这与普通变量赋值本质上是一样的,也就是说可以把某结构体变量成员的引用一起当作一个变量来使用,因此也可以用输入语句来赋值。

其中结构体成员赋值的三个语句为:S1.SAL=800、80例9.2学生记录包含如下数据项:姓名、一门功课的成绩、性别、家庭住址,要求打印学生各数据项,并求出该门成绩的平均值。程序如下: TYPESTUDENT CHARACTER(15)NAME INTEGERGRADE LOGICALSEX CHARACTER(30)ADDRESS ENDTYPE TYPE(STUDENT)::S1,S2,S3例9.2学生记录包含如下数据项:姓名、一门功课的成绩、性别81

PRINT*,"请输入三个学生的名字" READ*,S1.NAME,S2.NAME,S3.NAME PRINT*,"请输入三个学生的成绩" READ*,S1.GRADE,S2.GRADE,S3.GRADE PRINT*,"请输入三个学生的性别" READ*,S1%SEX,S2%SEX,S3%SEX PRINT*,"请输入三个学生的住址" READ*,S1.ADDRESS,S2.ADDRESS,S3.ADDRESS PRINT*,"三个学生的名字为",S1.NAME,S2.NAME,S3.NAME PRINT*,"请输入三个学生的名字"82

PRINT*,"三个学生的性别为",S1%SEX,S2%SEX,S3%SEX PRINT*,"三个学生的住址为",S1.ADDRESS,S2.ADDRESS,$S3.ADDRESS AVER=(S1%GRADE+S2.GRADE+S3.GRADE)/3 PRINT*,"三个学生的平均成绩为:",AVER END PRINT*,"三个学生的性别为",S1%SEX,S283请输入三个学生的名字输入:ZHANGLIWANG回车请输入三个学生的成绩输入三个正整数如859080回车请输入三个学生的性别输入.F..T..F.回车请输入三个学生的住址输入:CHANGSHAGUANGZHOUBEIJING回车请输入三个学生的名字84

最后输出结果为三个学生的名字为 ZHANG LI WANG三个学生的性别为 F T F三个学生的住址为 CHANGSHA GUANGZHOU BEIJING三个学生的平均成绩为 85最后输出结果为859.3.2定义的同时赋值

在定义结构体变量的同时,给定结构体各成员的值。其格式为:TYPE(派生数据类名)::结构体变量名=派生数据类名(成员初值表)其中,=后面的派生类名即为TYPE后面的派生类名;成员之间的值用“,”隔开。例如结构体如下:

9.3.2定义的同时赋值在定义结构体变量的同时,给定结构86 TYPETEACHER CHARACTER(12)NAME LOGICALSEX CHARACTER(15)POSITCHARACTER(30)ADDRESS INTEGERSALENDTYPE这样我们可以用如下方式给对应的结构体变量赋值:TYPE(TEACHER)::S1=TEACHER("ZHANG",.TRUE.,"PROFESSOR",”CHANGSHANG”,2000),S2,S3这样,结构体变量S1的值全部被给定。

TYPETEACHER87这种赋值方式应当注意:

(1)赋值时,所给的值类型和个数应与结构体变量定义中各成员的类型与个数保持一致。(2)可以将一个结构体变量的值直接赋给另外一个结构体变量,

这种赋值方式应当注意:(1)赋值时,所给的值类型和个数应与88INTEGERS TYPESTUDENTRECORD CHARACTER(15)NAME INTEGERNUM LOGICALSEX CHARACTER(30)ADDRESS ENDTYPE TYPE(STUDENTRECORD)::S1,S2 S1=STUDENTRECORD("ABCD",20,.TRUE.,"CHANGSHA") S2=S1 S=S2%NUM+S1%NUM PRINT*,S ENDINTEGERS89这里,通过S2=S1语句,使S1和S2两个结构体变量得到相同的值,输出S的结果为40。当结构体中包含成员较多时,可以用嵌套定义的方式,使结构体变得简洁,如例9.2中,当学生的成绩是多门时,可以将它们单独定义在一个结构体中,然后将该结构体包含到主结构体中,下面再看一个例子:

这里,通过S2=S1语句,使S1和S2两个结构体变量得到相同90例9.3、学生信息包含如下数据项:姓名、性别、学号、年龄和5门功课的成绩:语文、数学、物理、化学、英语,要求输入三个学生的记录,打印出相关信息与总成绩。分析:学生的成绩有5门,可以将它们放在一个名为STUDENTSCORE的结构体中,而将学生所有记录存放在名为STUDENTRECORD的结构体中,该结构体包含结构体STUDENTSCORE,然后作相应处理,注意学生成绩输入语句。程序如下:

例9.3、学生信息包含如下数据项:姓名、性别、学号、年龄和591PROGRAMXUESHENGJILU REALAVER1,AVER2,AVER3TYPESTUDENTSCORE REALCHINESE REALMATH REALPHYSICS REALCHEMISTRY REALENGLISH ENDTYPEPROGRAMXUESHENGJILU92TYPESTUDENTRECORD CHARACTER(17)NAME LOGICALSEX INTEGERNUMBER INTEGERBIRTHDAY TYPE(STUDENTSCORE)::SCORE ENDTYPE TYPE(STUDENTRECORD)::S1,S2,S3 PRINT*,"请输入3个学生的姓名" READ*,S1.NAME,S2.NAME,S3.NAME PRINT*,"请输入3个学生的性别" READ*,S1.SEX,S2.SEX,S3.SEX PRINT*,"请输入3个学生的学号" READ*,S1.NUMBER,S2.NUMBER,S3.NUMBER PRINT*,"请输入3个学生的年龄" READ*,S1.BIRTHDAY,S2.BIRTHDAY,S3.BIRTHDAYTYPESTUDENTRECORD93PRINT*,"请输入3个学生的语文成绩" READ*,S1%SCORE%CHINESE,S2%SCORE%CHINESE,S3%SCORE%CHINESE PRINT*,"请输入3个学生的数学成绩" READ*,S1%SCORE%MATH,S2%SCORE%MATH,S3%SCORE%MATH PRINT*,"请输入3个学生的物理成绩" READ*,S1%SCORE%PHYSICS,S2%SCORE%PHYSICS,S3%SCORE%PHYSICS PRINT*,"请输入3个学生的化学成绩" READ*,S1%SCORE%CHEMISTRY,S2%SCORE%CHEMISTRY,S3%SCORE%CHEMISTRY PRINT*,"请输入3个学生的英语成绩" READ*,S1%SCORE%ENGLISH,S2%SCORE%ENGLISH,S3%SCORE%ENGLISH AVER1=(S1%SCORE%CHINESE+S1%SCORE%MATH+S1%SCORE%PHYSICS+S1%SCORE%CHEMISTRY+S1%SCORE%ENGLISH)/5.0PRINT*,"请输入3个学生的语文成绩"94

AVER2=(S2%SCORE%CHINESE+S2%SCORE%MATH+S2%SCORE%PHYSICS+S2%SCORE%CHEMISTRY+S2%SCORE%ENGLISH)/5.0 AVER3=(S3%SCORE%CHINESE+S3%SCORE%MATH+S3%SCORE%PHYSICS+S3%SCORE%CHEMISTRY+S3%SCORE%ENGLISH)/5.0 PRINT*,S1.NAME,S1.SEX,S1.NUMBER,S1.BIRTHDAY PRINT*,S1%SCORE%CHINESE,S1%SCORE%MATH,S1%SCORE%PHYSICS,$S1%SCORE%CHEMISTRY,S1%SCORE%ENGLISH,AVER1 AVER2=(S2%SCORE%CHINESE+S295PRINT*,S2.NAME,S2.SEX,S2.NUMBER,S2.BIRTHDAY PRINT*,S2%SCORE%CHINESE,S2%SCORE%MATH,S2%SCORE%PHYSICS,$S2%SCORE%CHEMISTRY,S2%SCORE%ENGLISH,AVER2 PRINT*,S3.NAME,S3.SEX,S3.NUMBER,S3.BIRTHDAY PRINT*,S3%SCORE%CHINESE,S3%SCORE%MATH,S3%SCORE%PHYSICS,$S3%SCORE%CHEMISTRY,S3%SCORE%ENGLISH,AVER3 ENDPRINT*,S2.NAME,S2.SEX,S2.NUMBE969.5综合实例

在这一节中,我们结合数据处理中的一些常见操作,如数据的排序、插入、查找、删除、更新等,介绍结构体的综合应用实例。为了简便起见,我们同样以学生信息为例,且假设学生信息仅仅包含姓名和一门功课的成绩,另外加一个唯一的标识(如学号),现在考虑如何完成上述的操作。首先定义学生结构体如下:

9.5综合实例在这一节中,我们结合数据处理中的一些常见97TYPESTUDENTRECORDCHARACTER(15) NAMEINTEGER MARKINTEGER GRADEENDTYPESTUDENTRECORD其中:NAME代表学生姓名,MARK代表标示,GRADE代表成绩

TYPESTUDENTRECORD98其次必须考虑的是如何存储学生信息的问题。为此,定义如下结构体数组:TYPE(STUDENTRECORD),DIMENSION(STNUM)::STRECORD其中,STNUM为符号常量,代表学生人数,可以在使用之前通过INTEGER,PARAMETER::STNUM=20来定义,该语句的含义为定义一个整型的符号常量STNUM,其值为20,可以根据学生人数修改其值,下面一步一步地介绍完成上述的操作。

其次必须考虑的是如何存储学生信息的问题。999.5.1排序

排序(SORTING)是数据处理领域中最常用的一种运算,分为升序和降序排序两种,排序方法较多,常见的有简单交换排序、选择排序、冒泡排序、堆排序、快速排序、归并排序等,不同的排序方法,有不同的优点和缺点,但其中某些排序牵涉到数据结构方面的知识,如堆排序,已超出本书范围,读者如果有兴趣,可以参看有关数据结构方面的知识,这里仅仅使用简单交换法排序。排序的主要目的之一是为了查找方便,因此一般牵涉到排序字或称关键词(KEY)问题,这里用每个学生的标识MARK作为关键字进行排序字,如果要对学生的成绩排序,只须将MARK改为GRADE即可。

9.5.1排序排序(SORTING)是数据处理领域中最常100简单交换法思想介绍如下:先将除第一个数据项以外的所有数据与第一个数据项比较,前者小,则将与它有关的记录与后者有关的记录交换,显然,第一轮排序进行完毕,排序项最小者将被交换到最前面。然后从第二个排序项开始重复前述操作,依次类推,直到排序完成止。我们定义SORT函数来完成排序操作,程序如下:简单交换法思想介绍如下:101

SUBROUTINESORT(STRECORD,N) TYPESTUDENTRECORDCHARACTER(15) NAME INTEGER MARK INTEGER GRADE ENDTYPESTUDENTRECORD INTEGER,PARAMETER::STNUM=5 TYPE(STUDENTRECORD),DIMENSION(STNUM)::STRECORD TYPE(STUDENTRECORD)::TEMP INTEGERI,J,NSUBROUTINESORT(STRECORD,N)102 DO I=1,N DO J=I+1,N IF(STRECORD(I)%MARK>STRECORD(J)%MARK)THEN TEMP=STRECORD(I) STRECORD(I)=STRECORD(J) STRECORD(J)=TEMP ENDIFENDDOENDDOEND

DO I=1,N1039.5.2查找

查找(SEARCH)同人们日常生活有着密切的联系。如从字典中查找单词,从工资表中查找工资,从电话号码薄中查找电话,从图书馆中查找书,从地图上查找路线和地址等。同排序一样,查找的方法非常多,如顺序查找、二分查找、索引查找、分块查找、B_树查找等,这里介绍无序情况下的顺序查找和有序情况下的二分查找两种。

9.5.2查找查找(SEARCH)同人们日常生活有着密104

一、顺序查找

顺序查找的基本思想是:先输入待查找的标示KEY,从第一个开始,将它与已经存放好的学生记录中相应的项(在这里用MARK)比较,如果KEY与MARK相同,说明已找到,这时可以输出相关信息,如果KEY与MARK不同,则拿下一个记录中的MARK与KEY比较,直到找到或者到最后一个记录止,并输出相关的信息。程序如下:

一、顺序查找

顺序查找的基本思想是:先输入待查找的标示KE105SUBROUTINESORT_SEARCH(STRECORD,N,KEY) TYPESTUDENTRECORD CHARACTER(15)NAME INTEGERMARK INTEGER GRADE ENDTYPESTUDENTRECORD INTEGER,PARAMETER::STNUM=5 TYPE(STUDENTRECORD),DIMENSION(STNUM)::STRECORD INTEGERI,N,KEYSUBROUTINESORT_SEARCH(STRECOR106

I=1 DOWHILE((STRECORD(I)%MARK.NE.KEY).AND.(I.LE.N)) I=I+1ENDDO IF(I<=N)THEN PRINT*,"学生已经找到,其他相关的信息为:" PRINT*,"姓名为:",STRECORD(I)%NAME PRINT*,"成绩为:",STRECORD(I)%GRADE ELSE PRINT*,"查无此人" ENDIF END

I=11072.二分查找

二分查找,又称折半查找。作为二分查找对象的表必须是有序表,其最大的优点是查找速度非常快,数据越多,效果越明显。其基本思想如下:定义一个TOP指针(在这里可以理解为数组的第一个下标)指向表的第一个元素,定义一个BOT指针,指向表的最后一个元素,一个MID指针指向表的中间元素(靠左),即MID=(TOP+BOT)/2取下限,每一次查找,总是将待查项与MID指针所对应的元素的对应项比较,如果对应项刚好就是要查找的项,则说明已经找到,可以输出相关的信息;如果对应项小于待查项,则改BOT=MID-1,重新计算MID,然后重复前面的比较;如果对应项大于待查项,则改TOP=MID+1,重新计算MID,然后重复前面的比较。这样如果到TOP大于BOT还没有找到对应待查项,说明该项不在此表中。程序如下:

2.二分查找二分查找,又称折半查找。作为二分查找对象的表必108SUBROUTINEHALF_SEARCH(STRECORD,TOP,BOT,KEY) TYPESTUDENTRECORD CHARACTER(15)NAME INTEGERMARK INTEGER GRADE ENDTYPESTUDENTRECORD INTEGER,PARAMETER::STNUM=5 TYPE(STUDENTRECORD),DIMENSION(STNUM)::STRECORD

SUBROUTINEHALF_SEARCH(STRECOR109 INTEGERTOP,BOT,MID,KEY MID=(TOP+BOT)/2 DO100WHILE((STRECORD(MID)%MARK.NE.KEY).AND.(TOP.LE.BOT)) IF(STRECORD(MID)%MARK<KEY)THEN TOP=MID+1 ELSE BOT=MID-1 ENDIF MID=(TOP+BOT)/2 INTEGERTOP,BOT,MID,KEY110100 CONTINUE

IF(TOP<=BOT)THEN

PRINT*,"学生已经找到,其他相关的信息为:"

PRINT*,"姓名为:",STRECORD(MID)%NAME

PRINT*,"成绩为:",STRECORD(MID)%GRADE

ELSE

PRINT*,"查无此人"

ENDIF

END

100 CONTINUE

IF(TOP<=BOT)THE1119.5.3插入

插入是在原有信息的基础上加入一个新的记录,一般而言,分为表头插入,表尾插入和有序插入,这里主要介绍有序插入。所谓有序插入在根据关键字排好序的有序表中,插入一个新的记录,方法如下:先查找位置,将新记录的关键字与有序表中关键字比较,如果新记录的关键字小于当前比较的关键字,则拿下一个记录的关键字与新记录比较,直到表中记录的关键字大于新记录止,这时说明新记录应当插入该记录的前面。

9.5.3插入插入是在原有信息的基础上加入一个新的记录,112然后是表中记录的移动,这时,先应从当前表中最后一个记录开始到关键字刚好大于新记录的所有项依次后移。最后将新记录的置于查找到的位置即完成插入操作。为了理解该算法,下面用一个具体实例来对其进行说明。假设某有序表关键字依次如下:1 3 5 7 8 10 12 16新插入的记录关键字为4,则插入过程示意图如下:然后是表中记录的移动,这时,先应从当前表中最后一个记录开始到113

关键字为4的新记录插入位置1 3 5 7 8 10 12 16关键字为4的新记录插入位置1 3 5 7 8 10 12 114元素后移动以后结果:1 3 5 5 7 8 10 12 16其中第一个5所在的记录在将被新记录覆盖。插入新记录后,按关键字显示的结果为1 3 4 5 7 8 10 12 16

元素后移动以后结果:115程序如下:SUBROUTINESORT_INSERT(STRECORD,NEW,N)TYPESTUDENTRECORDCHARACTER(15)NAMEINTEGER MARKINTEGER GRADEENDTYPESTUDENTRECORD INTEGER,PARAMETER::STNUM=5程序如下:116 TYPE(STUDENTRECORD),DIMENSION(STNUM+1)::STRECORD TYPE(STUDENTRECORD)::NEW INTEGERI,N,JI=1 DO WHILE((STRECORD(I)%MARK.LT.NEW%MARK).AND.(I.LE.N-1)) I=I+1ENDDO DOJ=N-1,I,-1 STRECORD(J+1)=STRECORD(J) ENDDOSTRECORD(I)=NEW END

TYPE(STUDENTRECORD),DIMENS1179.5.4删除

删除操作也是数据处理中常见的操作之一,要

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论