第7章 结构体改编_第1页
第7章 结构体改编_第2页
第7章 结构体改编_第3页
第7章 结构体改编_第4页
第7章 结构体改编_第5页
已阅读5页,还剩69页未读 继续免费阅读

下载本文档

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

文档简介

第7章结构体与链表7.1结构体的引出7.2结构体变量7.3结构体数组7.4结构体类型的指针变量7.5结构体与函数7.6链表在实际问题中我们常需要把不同类型的几个数据组合起来,构成一个整体,如学校中教师和学生的信息。学号姓名性别年龄入学成绩所属学院0501李明男19610信息0502张莉女19595信息0503王涛男20580控制职工编号姓名性别民族出生日期职称学历单位工龄1997025孙杰男汉1974.9讲师大学信息92001016赵玫女回1978.3助教大学控制51985104郑毅男汉1964.11教授大学管理217.1结构体的引出学号姓名性别年龄入学成绩所属学院0501李明男19610信息0502张莉女19595信息0503王涛男20580控制如何表示这样的数据信息?结构体是由一些逻辑相关,但数据类型不同的分量组成的一组数据。学号姓名性别年龄入学成绩所属学院intnumcharname[10]charsexintageintscorecharinstitute[20]例:输入三个学生的信息,并输出#include<stdio.h>voidmain(){structstudent{intnum;charname[10];charsex;

intage;

intscore;charinstitute[20]};

structstudents1,s2,s3;

定义学生的结构体类型定义3个结构体类型的变量,用来存放3个学生的信息7.1结构体的引出structstudent{intnum;charname[10];charsex;

intage;

intscore;charinstitute[20]};7.2.1结构体的定义注意:定义了结构体类型,仅仅是定义了数据的组织形式,创立了一种数据类型,但并不会为这种结构体类型分配内存空间只有定义了结构体变量,才会为变量分配空间注意不要忘了分号成员表列struct

结构体类型名{数据类型成员名1;

数据类型成员名2;::

数据类型成员名n;}

;关键字用户定义的标识符7.2结构体变量定义结构体变量的方法(1)先定义结构体类型,再定义变量

structstudent{charname[10];

intage;

ints1,s2;};

structstudentst1,st2;st1st2nameages1s2nameages1s2内存中结构体变量占有一片连续的存储单元,其占用的字节数可用sizeof

运算符算出:

printf(“%d\n”,sizeof(structstudent));

printf(“%d\n”,sizeof(st1));结构体变量st1和st2各自都需要22个字节的存储空间结构体类型定义结构体变量定义7.2结构体变量定义结构体变量的方法(2)定义结构体类型同时定义变量

structstudent{charname[10];

intage;

ints1,s2;}

st1,st2;(3)直接定义结构体变量

struct

{charname[10];

intage;

ints1,s2;}

st1,st2;注意:这里没有结构体类型名这种方式有时使用并不方便因此不建议大家采用定义结构体变量7.2结构体变量例:

structdate{intyear;

intmonth;

intday;};

structstud{charname[10];

structdatebirthday;

ints1,s2;};结构体类型可以嵌套定义

或:structstud{charname[10];

structdate{intyear;

intmonth;

intday;}birthday;

ints1,s2;};7.2结构体变量7.2.2结构体变量的引用和初始化格式:

结构体变量名.

成员名structstudent{charname[10];

intage;

ints1,s2;};structstudentst1;st1.

name

=“Mary”;st1.age

=21;st1.

s1

=78;st1.

s2

=86;说明:一般情况下都是对结构体变量的成员进行赋值和输入\输出7.2结构体变量structdate{intyear;

intmonth;

intday;};structstud{charname[10];

intage;

structdatebirthday;

ints1,s2;};structstudst2;intage,year;=“John”;st2.age=20;st2.birthday.year=1980;st2.birthday.month=11;st2.birthday.day=23;st2.s1=89;st2.s2=95;age=24;year=2000;可以定义与结构体成员名相同名字的变量,它们之间不会发生混乱相同类型的结构体变量可以进行整体赋值

structdate{intyear;

intmonth;

intday;};structstud{charname[10];

intage;

structdatebirthday;

ints1,s2;};structstudst1,st2,st3;=“John”;st1.age=20;st1.birthday.year=1980;st1.birthday.month=11;st1.birthday.day=23;st1.s1=89;st1.s2=95;st2=st1;=“Mary”;st3.age=20;st3.birthday=st1.birthday;st3.s1=76;st3.s2=85;注意要正确赋值的条件是变量st1已经有了数据7.2结构体变量structstudent{charname[10];

intage;

ints1,s2;}

st1={“Mary”,21,78,86};structstud{charname[10];

structdatebirthday;

ints1,s2;};structstudst2={“John”,

1980,11,23

,89,95};structstudent{charname[10];

intage;

ints1,s2;};structstudentst1;

st1={“Mary”,21,78,86};初始化,正确这是赋值,错误C不允许这么做初始化,正确7.2.2结构体变量的引用和初始化结构体变量的输入输出

C语言不允许结构体变量整体进行输入和输出,

只能对结构体变量的成员进行输入和输出gets(

);scanf(“%d%d%d”,

&st1.birthday.year

,

&st1.birthday.month,

&st1.birthday.day);scanf(“%d%d%d”,

&st1.age,

&st1.s1,

&st1.s2);

puts();printf(“%4d”,st1.age);printf(“%d.%d.%d”,st1.birthday.year,st1.birthday.month,st1.birthday.day);printf(“%4d%4d\n”,st1.s1,st1.s2);7.2.2结构体变量的引用和初始化7.3结构体数组学号姓名性别年龄入学成绩所属学院0501李明男19610信息0502张莉女19595信息0503王涛男20580控制7.3.1结构体数组的定义一个结构体变量只能存放一个学生的信息,对于多个学生的信息,可以使用一个结构体数组来存放,结构体数组的每个元素是一个结构体类型的变量定义结构体数组的方法与定义普通数组的方法类似:结构体类型数组名[数组的长度];例:输入30个学生的信息,并输出#include<stdio.h>voidmain(){structstudent{intnum;charname[10];charsex;

intage;

intscore;charinstitute[20]};

structstudents[30];

inti;

for(i=0;i<30;i++){scanf(“%c%d%d%d”,&s[i].sex,&s[i].num,&s[i].age,&s[i].score);gets(s[i].name);gets(s[i].institute);}for(i=0;i<30;i++){printf(“%6d%10s%2c%3d”,s[i].num,s[i].name,s[i].sex,s[i].age);

printf(“%5d%20s\n”,s[i].score,s[i].institue);}}7.3结构体数组7.3.1结构体数组的定义1、定义结构体数组(1)先定义结构体类型再定义结构体数组

structstudent{charname[10];

intage;

ints1,s2;};structstudentst[6];(2)定义结构体类型的同时定义结构体数组

structstudent

{charname[10];

intage;

ints1,s2;}

st[6];(3)直接定义结构体数组

struct

{charname[10];

intage;

ints1,s2;}

st[6];不提倡使用该方法7.3.2结构体数组的初始化将每个数组元素的数据用花括号{}括起来structstudent{charname[10];

intage;

ints1,s2;};structstudentst[3]={

{“Mary”,21,78,86},

{“Alex”,20,90,80},

{“Mike”,19,75,68}

};Mary217886Alex209080Mike197568st[0]st[1]st[2]7.3结构体数组(2)数组元素之间可以整体赋值也可以将一个元素赋给一个相同类型的结构体变量structstudent

st[3]={

{“Mary”,21,78,86},{“Alex”,…}

};structstudent

x;st[2]=st[0];x=st[1];都是结构体变量的整体赋值形式7.3.3结构体数组的使用(1)引用某个数组元素的成员

例:puts(

st[0].name

);

printf(“%d,%d”,

st[1].age,st[1].s1

);(3)输入和输出操作只能对数组元素的成员进行7.3结构体数组分析:假设有3个候选人,共有100个人投票定义一个结构体数组,它有3个元素代表3个候选人,每个元素有2个成员,一个是候选人名字,一个是得票数(初始时为0)例:设计一个对候选人得票进行统计的程序候选人票数Mike0John0Alex0有100张选票,输入选票上的名字,然后判断是谁的名字,就将谁的票数加1,重复100次最后输出结构体数组#include<stdio.h>#include<string.h>structperson{charname[10];

intcount;};voidmain(){structperson

cand[3]={{“Li”,0},{“Zhang”,0},{“Fun”,0}};

inti,j;charcname[20];for(i=0;i<100;i++){scanf(“%s”,cname);for(j=0;j<3;j++)if(strcmp(cname,cand[j].name)==0)cand[j].count++;

}for(i=0;i<3;i++)

printf(“%10s:%d\n”,cand[i].name,cand[i].count);}定义候选人的结构体类型对结构体数组进行初始化//输入选票上的名字//若有100人投票,则循环100次//将选票上的名字依次和候选人的名字比较//选票上名字和某个候选人名字相同时,其票数加1例:按成绩对学生信息进行从高到底的排序#include<stdio.h>#defineN30structstud{intn;//学生学号charname[10];//学生姓名

ints;//学生成绩};voidinput(structstud

a[]){inti;for(i=0;i<N;i++)

scanf(“%d%s%d”,&a[i].n,a[i].name,&a[i].s);

}voidoutput(structstud

a[

]){inti;for(i=0;i<N;i++)

printf(“%4d%10s%4d”,a[i].n,a[i].name,a[i].s);

}

注意a[i].name前不加&,因name是数组名,因用%s,输入时名字不能加空格voidsort(structstud

a[]

){inti,j;

structstud

temp;

for(i=0;i<N-1;i++)for(j=i+1;j<N;j++)

if(a[i].s<a[j].s)

{temp=a[i];a[i]=a[j];a[j]=temp;}}voidmain(){

structstud

st[N];

input(st);sort(st);output(st);}注意进行比较的是元素a[i]和a[j]的成绩成员s,但进行交换的是元素a[i]和a[j]例:用冒泡排序法对6个数进行排序(从小到大)

9

7

2

5

4

1a[0]a[1]a[2]a[3]a[4]a[5]

7

2

5

4

1

92775471

2

5

4

1

7

94515

2

4

1

5

7

9

2

1

4

5

7

91412冒泡排序方法:依次比较相邻的两个数,将小数放前面,大数放后面.n个数排序需要进行n-1轮比较,从第1轮到第n-1轮,各轮的比较次数依次为:n-1次、n-2次…1次

9

7

2

5

4

19999972541初始状态第1轮第2轮第3轮第4轮第5轮74.1一维数组冒泡排序#include<stdio.h>#defineN6voidmain(){int

a[N],i,j,t;

for(i=0;i<N;i++)

scanf(“%d”,&a[i]);

for(i=0;i<N-1;i++)for(j=0;j<N-1-i;j++)if(a[j]>a[j+1]){t=a[j];

a[j]=a[j+1];a[j+1]=t;

}for(i=0;i<N;i++)

printf(“%3d”,a[i]);}冒泡排序的改进方法

#include<stdio.h>voidmain(){inta[6],i,j,t,flag;for(i=0;i<6;i++)

scanf(“%d”,&a[i]);

i=0;

do{flag=0;for(j=0;j<5-i;j++)if(a[j]>a[j+1]){t=a[j];a[j]=a[j+1];a[j+1]=t;flag=1;

}

i++;

}while(flag);for(i=0;i<6;i++)

printf(“%3d”,a[i]);}例:用选择排序法对6个数进行排序(从小到大)

9

7

2

5

4

1a[0]a[1]a[2]a[3]a[4]a[5]选择排序方法:第1轮比较时,用a[0]依次与a[1]到a[5]进行比较,如果a[0]较大则进行交换,第1轮结束后,a[0]中为最小数.以后各轮比较过程与第1论类似.

1

9

7

5

4

2

1

2

9

7

5

479574524

1

2

4

9

7

5

1

2

4

5

9

7795745

9

7

2

5

4

1729712初始状态第1轮第2轮第3轮第4轮第5轮7957794.1一维数组选择排序#include<stdio.h>#defineN6voidmain(){int

a[N],i,j,t;for(i=0;i<N;i++)

scanf(“%d”,&a[i]);

for(i=0;i<N-1;i++)for(j=i+1;j<N;j++)if(a[i]>a[j]){t=a[i];

a[i]=a[j];

a[j]=t;

}for(i=0;i<N;i++)

printf(“%3d”,a[i]);}选择排序改进方法#include<stdio.h>voidmain(){inta[6],i,j,k,t;for(i=0;i<6;i++)

scanf(“%d”,&a[i]);for(i=0;i<5;i++){k=i;for(j=i+1;j<6;j++)if(a[k]>a[j])k=j;if(k!=i){t=a[i];a[i]=a[k];

a[k]=t;}//endif}//endforfor(i=0;i<6;i++)

printf(“%3d”,a[i]);}7.4结构体类型的指针变量

7.4.1指向结构体变量的指针

1.定义

structstudent

{charname[20];

intage;

ints1,s2;};

structstudent

stu,*p;

p=&stu;2.成员的引用格式(1)结构体变量名.成员名

gets(

);(*p).age

=21;p->s1

=87;p->s2

=90;(2)(*指针变量名).成员名

(*p).age(3)指针变量名->成员名

p

->s1typedef

structstudent{charname[20];

intage;

ints1,s2;}SD;

SDx,stu,*p;

p=&stu;成员的引用格式(1)结构体变量名.成员名例:scanf(“%s”,);scanf(“%d”,&x.age);x.s1=89;x.s2=78;gets();(*p).age=21;scanf(“%d”,&p->s1);p->s2=90;(2)(*指针变量名).成员名(*p).age(3)指针变量名->成员名p->s17.4结构体与指针说明:和成员运算符一样,“->”为指向运算符,是运算优先级最高的运算符。由于成员运算符“.”的运算优先级高于运算符“*”,

因此(*p).成员名中()不能少。*p.成员名p=&stu.score;

不能用指向某个结构体变量的指针指向该结构体变量的某个成员。7.4.2指向结构体数组的指针1.定义structstudent

a[3],*p

;2.使用for(

p=a;p<a+3;p++

){gets(

p->name);

scanf(“%d%d%d”,&p->age,&p->s1,&p->s2);}

7.4结构体与指针例如:

struct

struct_name{charname[10];

intnum;floatscore;};/*定义结构体类型标识符*/

struct

struct_namestd[30],*p;900390赵明879002王建899001李红结构体数组stdstd[0]std[1]std[2]p赋值语句p=std;/*p指向一个结构体数组std*//*指针变量p存放的是数组std的首地址*/引用:p->name;p->num;p->score;赵明909003879002王建899001李红结构体数组stdstd[0]std[1]std[2]思考:赋值语句

p=std+1;和p++;分别代表指针p指向哪里?p->name;p->num;p->score;代表的信息发生了什么变化?pp注意:以下赋值语句都是错误的:p=&std[1].score;(不能指向数组元素的成员变量)p=&std;(数组名本身就代表该数组的首地址,因此不能使用地址运算符&)7.5.1结构体变量作为函数参数1.函数实参和形参都用结构体变量,参数之间为值传递,实参结构体变量各成员的值依次传给形参结构体变量2.返回结构体类型值的函数定义格式:结构体类型名函数名(形参表){函数体;}

例:structstudentfunct(intx,floaty){函数体;}注意:结构体类型是已经定义好的7.5结构体与函数#include<stdio.h>#defineN5structstud{charname[10];

ints[3];

intsum,ave;};structstud

count(structstudx){intj;

x.sum=0;for(j=0;j<3;j++)

x.sum=x.sum+x.s[j];

x.ave=x.sum/3;

return(x);}例:求学生成绩的总分和平均分(结构体变量作参数)//定义学生的结构体类型//计算学生三门课的总分//返回学生的全部信息//结构体变量作参数返回结构体类型的值voidmain(){structstuda[N];

intj;for(j=0;j<N;j++)

scanf(“%s%d%d%d”,a[j].name,&a[j].s[0],

&a[j].s[1],&a[j].s[2]);

for(j=0;j<N;j++)

a[j]=count(a[j]);

for(j=0;j<N;j++)printf(“%10s%4d%4d%4d%6d%4d\n”,a[j].name,a[j].s[0],a[j].s[1],a[j].s[2],a[j].sum,a[j].ave);}//函数调用,将a[j]的值传给count函数的参数x,并将返回值赋给a[j]//输入N个学生的信息//定义结构体数组a,存放N个学生的信息void

count(structstud*p){intj;p->sum=0;for(j=0;j<3;j++)p->sum=p->sum+p->s[j];p->ave=p->sum/3;}例:求学生成绩的总分和平均分(指向结构体的指针作参数)#include<stdio.h>#defineN5structstud{charname[10];

ints[3];

intsum,ave;};//指向结构体的指针作参数返回结构体类型的值voidmain(){structstuda[N];

intj;for(j=0;j<N;j++)

scanf(“%s%d%d%d”,a[j].name,&a[j].s[0],

&a[j].s[1],&a[j].s[2]);

for(j=0;j<N;j++)

count(&a[j]);

for(j=0;j<N;j++)printf(“%10s%4d%4d%4d%6d%4d\n”,a[j].name,a[j].s[0],a[j].s[1],a[j].s[2],a[j].sum,a[j].ave);}voidmain(){structstuda[N],*q;

intj;

q=a;for(j=0;j<N;j++)

scanf(“%s%d%d%d”,q->name,&a[j].s[0],

&a[j].s[1],&a[j].s[2]);

for(j=0;q<a+N;q++)

count(q);

for(j=0;j<N;j++)printf(“%10s%4d%4d%4d%6d%4d\n”,a[j].name,a[j].s[0],a[j].s[1],a[j].s[2],a[j].sum,a[j].ave);}7.6链表链表:是可以动态地进行存储分配的一种数据结构它是由一组动态数据链接而成的序列结点:链表中的每一个动态数据称为一个结点表头结点表尾结点NULL为空地址

表示链表到此结束2010142815709514281861570282NULL3中间结点一.、基本概念1.动态存储分配:根据需要临时分配内存单元用以存放数据,

当数据不用时可以随时释放内存单元2.链表:是可以动态地进行存储分配的一种数据结构它是由一组动态数据链接而成的序列3.结点:链表中的每一个动态数据称为一个结点4.结点类型:是一个包含指针项的结构体类型一般由两部分组成:(1)数据成员:存放数据(2)指针成员:存放下一个结点的地址struct

sd{intnum;

intscore;

struct

sd*next;};

数据成员指针成员链表的基本概念2010142815709514281861570282NULL3链表的基本概念2010head2010142815709514281861570282NULL3链表的每个结点存放在内存中的不同位置,只有找到第1个结点,才能通过第1个结点的指针成员找到第2个结点…因此我们将第1个结点的地址存放在头指针中头指针链表的长度是不固定的,可以随时添加结点,如果将一个结点添加到链表的尾部,则新结点成为表尾结点,它的指针成员必须赋为NULL,而原来的表尾结点则成为中间结点75NULL436923692静态简单链表#include<stdio.h>typedef

structstud{intnum,score;

structstud*next;}SD;head2010142815702010abc19514282861570382NULLp201014281570NULLvoidmain(){SD

a,b,c,*head,*p;

head=&a;a.num=1;a.score=95;a.next=&b;b.num=2;b.score=86;b.next=&c;c.num=3;c.score=82;c.next=NULL;

p=head;while(p!=NULL){printf(“%3d%4d\n”,p->num,p->score);

p=p->next;}}静态简单链表#include<stdio.h>typedef

structstud{intnum,score;

structstud*next;}SD;voidmain(){SDa,b,c,*head,*p;head=&a;

a.num=1;a.score=95;a.next=&b;

b.num=2;b.score=86;b.next=&c;

c.num=3;c.score=82;c.next=NULL;

while(head!=NULL){printf("%3d%4d\n",head->num,head->score);head=head->next;}}//也可以实现上一页的功能动态链表的建立建立链表的方法表尾添加法:新结点作为表尾结点表首添加法:新结点作为表头结点95NULL1201086NULL21428201082NULL3157095NULL1201086NULL2142882NULL31570head201014281570head20101428处理动态链表所需的函数(需用头文件<stdlib.h>)1.malloc

函数原型:void*malloc(unsignedintsize)

作用:在内存中开辟一个长度为size的连续存储空间,

并将此存储空间的起始地址带回注意:(1)函数返回值是指针,但该指针是指向void类型的,因此在使用时希望这个指针指向其他类型需要用强制类型转换(2)如果内存缺少足够大的空间进行分配,则malloc

函数返回值为“空指针”(即NULL)例:struct

sd*p;p=

(struct

sd*)

malloc(

sizeof(struct

sd)

);强制类型转换结构体类型占用的字节长度2.free函数原型:voidfree(void*ptr)

作用:将指针变量ptr指向的存储空间释放注意:ptr的值不是任意的地址,必须是程序中执行malloc

函数所返回的地址(2)模型中ptr是void型,但调用free函数时,参数可能是其他类型,计算机系统会自动进行转换

例:struct

sd*p;p=(struct

sd*)malloc(sizeof(struct

sd));free(p);p42004200动态链表的建立表尾添加法建立链表#include<stdio.h>#include<stdlib.h>typedef

structstudent{intnum;

intscore;

structstudent*next;}ST;#defineLENsizeof(ST)intn;定义ST,以后书写简单求出结构体类型占用的字节数全局量n表示结点的个数ST*creat(void){ST*p1,*p2,*head=NULL;n=0;

p1=(ST*)malloc(LEN);if(p1==NULL){printf("\nNoenoughmemory!\n");exit(0);}

scanf("%d%d",&p1->num,&p1->score);while(p1->num!=0){n=n+1;if(n==1)head=p1;elsep2->next=p1;p2=p1;

p1=(ST*)malloc(LEN);if(p1==NULL){printf("\nNoenoughmemory!\n");exit(0);}

scanf("%d%d",&p1->num,&p1->score);}p2->next=NULL;

free(p1);return(head);}//产生一个新结点//输入新结点的数据成员//结点个数加1//让指针p2指向p1所指向的结点//表尾结点的指针成员赋为空//释放p1所指向的结点空间//p1指向新产生的结点//若n等于1,则p1当前所指向的是表头结点由于head头指针不变,所以让下一个结点p2记录表头结点的地址,让表头结点去产生一个新结点,这样再让p2->next指向新结点,即可产生链接表尾添加法建立链表的过程演示ST*creat(void){ST*p1,*p2,

*head;head=NULL;n=0;p1=(ST*)malloc(LEN);

scanf("%d%d",&p1->num,&p1->score);while(p1->num!=0){n=n+1;if(n==1)head=p1;elsep2->next=p1;p2=p1;p1=(ST*)malloc(LEN);

scanf("%d%d",&p1->num,&p1->score);}p2->next=NULL;free(p1);return(head);}head201014281570NULLp1p23264201020101951428n201014282863820014281570NULL1570157032640123动态链表的遍历(输出)输出链表voidlist(ST*head){ST*p;

p=head;while(p!=NULL){printf(“%d,%d\n”,p->num,p->score);

p=p->next;

}}head201014281570201019514282861570382NULLp201014281570NULL输出:1,952,863,82voidmain(){ST*h=NULL;

h=creat();list(h);}951428120108615702142882NULL315702010head链表的删除结点操作删除表头结点让头指针指向链表的第2个结点1428step1:让指针变量p指向要删除的结点即表头结点step2:重新给头指针赋值,使它指向第2个结点head=p->next;step3:释放删除的结点空间free(p);p=head;2010p应为要释放删除的结点,所以必须在知道此结点的地址的情况下,才能进行空间释放,所以让p记录此结点的地址。951428120108615702142882NULL315702010head链表的删除结点操作删除表尾结点将链表的倒数第2个结点的指针成员赋为NULLstep1:让指针变量p指向要删除的结点即表尾结点

让指针变量q指向要删除结点的前一个结点1570p1428qstep2:将删除结点的前驱结点的指针成员赋空值step3:释放删除的结点空间free(p);q->next=NULL;NULL951428120108615702142882NULL315702010head链表的删除结点操作删除中间结点step1:让p指向要删除的结点,

让q指向要删除结点的前驱结点1428p2010qstep2:前驱结点的指针成员赋为要删除结点的指针成员值step3:释放删除的结点空间free(p);q->next=p->next;让要删除结点的前驱结点指向要删除结点的后继结点1570ST*del(ST*head,intnum){ST*p,*q=NULL;p=head;

while((num!=p->num)&&(p->next!=NULL)){q=p;p=p->next;}if(num==p->num){if(p==head)head=p->next;elseq->next=p->next;

free(p);

n=n-1;

printf(“deleted!\n”);}elseprintf(“cannotdelete!\n”);

return(head);}typedef

structstudent{intnum;

intscore;

structstudent*next;}ST;链表的删除结点操作删除结点函数令p指向要删除的结点,q指向其前驱结点(方法)//删除结点为表头结点//删除结点为表尾结点或中间结点//释放已删除的结点空间//链表的结点个数减1//返回链表的头指针要求:删除与num相等的结点ST*p,*q=NULL;

p=head;while((num!=p->num)&&(p->next!=NULL)){q=p;p=p->next;}951428120108615702142882NULL315702010head2010pNULLq设num=32010142814281570让p指向要删除的结点,让q指向其前驱结点链表的删除结点操作链表的插入结点操作插入的结点作表头结点951428220108615705142882NULL815702010head75121062106p02010p12010让p0指向新结点即要插入的结点,让p1指向插入位置上的结点即表头结点head=p0;p0->next=p1;2106插入的结点作表尾结点9693652951428220108615705142882NULL815702010head让p0指向新结点即要插入的结点,让p1指向插入位置上的结点即表尾结点3652p01570p1NULL3652链表的插入结点操作p1->next=p0;p0->next=NULL;插入的结点作中间结点9262374951428220108615705142882NULL815702010head链表的插入结点操作让p0指向新结点即要插入的结点,让p1指向插入位置上的结点,p2指向p1的前驱结点2374p01570p11428p223741570p2->next=p0;p0->next=p1;链表的插入结点操作插入结点函数ST*insert(ST*head){ST*p0,*p1,*p2;p1=head;p0=(ST*)malloc(LEN);

scanf(“%d%d”,&p0->num,&p0->score);if(head==NULL){head=p0;p0->next=NULL;}else{while((p0->num>p1->num)&&(p1->next!=NULL)){p2=p1;p1=p1->next;}if(p0->num<=p1->num){if(head==p1)head=p0;elsep2->next=p0;p0->next=p1;}else{p1->next=p0;p0->next=NULL;}}n++;return(head);}//如果是空链表,则新结点是链表的表头结点//找到要插入结点的位置//插入结点作表头结点//插入结点作中间结点//插入结点作表尾结点//链表的结点个数加1链表的插入结点操作(1)插入链表的第一个结点ST*insert(ST*head){ST*p0,*p1,*p2;p1=head;p0=(ST*)malloc(LEN);

scanf(“%d%d”,&p0->num,&p0->score);

if(head==NULL){head=p0;p0->next=NULL;}

else{…}

n++;return(head);}headNULL1428p1p2p03861428NULL1428NULLn0

1链表的插入结点操作ST*insert(ST*head){ST*p0,*p1,*p2;p1=head;p0=(ST*)malloc(LEN);

scanf(“%d%d”,&p0->num,&p0->score);

if(head==NULL){…}

else{while((p0->num>p1->num)&&(p1->next!=NULL))

{…}

if(p0->num<=p1->num){if(head==p1)head=p0;

else…

p0->next=p1;}

else{…}}n++;return(head);}1428head1428386NULLn12p1p2p0

201020101428195(2)插入结点作表头结点14282010链表的插入结点操作ST*insert(ST*head){ST*p0,*p1,*p2;p1=head;p0=(ST*)malloc(LEN);

scanf(“%d%d”,&p0->num,&p0->score);

if(head==NULL){…}else{while((p0->num>p1->num)&&(p1->next!=NULL)){p2=p1;p1=p1->next;}

if(p0->num<=p1->num){…}

else{p1->next=p0;p0->next=NULL;}}n++;return(head);}1570(3)插入结点作表尾结点20101428head20101951428386NULLp2p0n2p1582NULL201020101428315707.8类型定义符typedef的用法

当用户定义一种结构体类型后,每次都需要用“struct

结构体类型名”来定义相应变量,稍显麻烦。C语言不仅提供了丰富的数据类型,而且还允许由用户自己定义类型说明符,也就是说允许由用户为数据类型取“别名”。类型定义符ty

温馨提示

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

评论

0/150

提交评论