vc++课件第八章.ppt_第1页
vc++课件第八章.ppt_第2页
vc++课件第八章.ppt_第3页
vc++课件第八章.ppt_第4页
vc++课件第八章.ppt_第5页
已阅读5页,还剩131页未读 继续免费阅读

下载本文档

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

文档简介

1、2020/8/8,1,第8章 指针和引用,2020/8/8,2,8.1指针和指针变量,指针的概念,在程序运行时,任何一个变量在内存中都要为其分配存储单元,存储单元按地址编号。变量占用内存单元的第一个字节的地址就是变量的指针。在程序运行过程中,可以将变量的指针(地址)赋给一种特殊类型的变量指针类型变量。,2020/8/8,3,指针变量说明方法 数据类型 *变量名1,*变量名2 , ,*变量名n; 如:int *p1,*p2; /说明了两个整型指针变量p1,p2 float *q1,*q2,*q3; /说明了三个实型指针变量q1,q2,q3 double *s; /说明了一个双精度型指针变量s 其

2、中:变量名前的“*”为一标志,指出该类型变量是指针类型变量,简称为指针变量.,2020/8/8,4,有关指针的特殊运算 “*” 是取内容运算符,用来读取它所指向的内存中的值。 “ pc= /将q赋给p,2020/8/8,7,例8-1:指针的赋值运算和算术运算。,#include void main(void) int a1=1,a2=2; int *p1,*p2,*p3; float *fp1,*fp2; float b1=23.5,b2=55.6; p1= /A将变量a的地址赋给p1,称指针变量p1指向变量a1,2020/8/8,8,p2=p1; /B同类型的指针变量之间的赋值 p3= ,2

3、020/8/8,9,程序执行后输出: *p1=1 *p2=1 *p3=2 p1=0 x0065FDDC p3=0 x0065FDD8 *fp1=23.5 *fp2=55.6,指针变量的访问有两种方法: 一是访问指针变量的值,另一是访问指针变量所指向的内存单元中的数据,这种访问称为访问指针的内容。,2020/8/8,10,注:1. C+中可将0赋给一指针变量,意为初始化,其值 为“空”。即该指针变量不指向任一内存单元,也就是不指向任一变量。如: #include void main(void) int *pt; pt=0; *pt=100;/出错,因pt不指向任一内存单元, /因而不允许给pt所

4、指向的内存单元赋值。 cout*ptn; 2. 不同类型的指针变量间可强制转换后赋值,但通常 没有意义。,2020/8/8,11,如:#include void main(void) int i=100,*p1; float x=2.5,*p3; p1= char name4; ; student *pst;,(2)指针的算术运算,pxn: pxnsizeof(T),px-py: ( px-py) / sizeof(T),px+n, px-n 将指针从当前位置向前或向后移动n个数据单位,而不是n个字节。 这取决于指针所指向的数据类型(T)。,px-py求出的是两指针位置之间的数据个数,而不是地

5、址差。,2020/8/8,13,例8-2:指针变量的“+”和“-”运算。,#include void main(void) int a10=100,200,300,400,500; int i=10, j=20,*p1= /p1指向变量j,输出*p1的值为20,2020/8/8,14,p1+; /p1加1,实际运算加4,因为一个整数型变量占四个字节 cout*p1=*p1tp1=(int)p1n; cout*p2=*p2tp2=(int)p2n; p2+; /开始时指向a的第0个元素,加1后指向a的第一个元素 cout*p2=*p2tp2=(int)p2n; cout*pc1=*pc1 pc1

6、=(int)pc1 n; ,2020/8/8,15,程序执行后输出: *p1=20 p1=6618552 *p1=10 p1=6618556 *p2=100 p2=6618576 *p2=200 p2=6618580 *pc1=a pc1=6618568,2020/8/8,16,注:C+中,同一个说明语句中所说明的变量均分配在同一个连续的存储空间,VC+按从右到左的顺序来分配。一般来说,分配的顺序随编译器不同而不同。,例8-3:指针变量加一常数。,#include void main(void) int a10=100,200,300,400,500; int *p2= ,2020/8/8,1

7、7,执行后输出:*p2=100 p2=6618576 *p2=500 p2=6618592 *p2=300 p2=6618584,2020/8/8,18,(3)指针的关系运算 指对两个相同类型的指针的运算,如pxpy,当px所指位置在py之前时,表达式的值为1,否则为0。 px= =0,px!=0用来判断px是否为空指针。 注:不同类型的指针以及指针和一般整数间的关系运算是无意义的。,例8-4:指针变量的关系运算。,#include void main(void) int a5=100,200,300,400,500; int *p2,*p1;,2020/8/8,19,执行后输出:100 20

8、0 300 400 500 元素之和为:1500,for(p2= ,2020/8/8,20,注:几种运算符的混合运算及其优先级。 (1)指针运算符“*”与取地址运算符“ for (int i=0; i4; i+) cout *(a+ i )= *(a+i) , a i = ai ; ,指针与数组的差异: 指针是地址变量,可任意改变它的值; 数组名是地址常量,其值不能改变。,结果: *(a+0)=11, a0=11, *(a+1)=22, a1=22, *(a+2)=33, a2=33, *(a+3)=44, a3=44,数组元素的引用,既可用下标法,也可用指针法。使用下标法,直观;而使用指针法

9、,能使目标程序占用内存少、运行速度快。,2020/8/8,24,通过指针变量操作一维数组,当指针变量(p)指向数组中的某个元素时,指针变量中存放的是该元素的地址,而*p是该元素的值。 如: int a10=1,3,5,7,9,11,13,15,17,19,*p1,*p2; p1=a; /等同于p1= / 先使p指向a0, /把a0的值赋给b后,p指向a1 p=a+1,b=*+p; / 先使p指向a1, /p后移指向a2,把a2的值赋给b p=a,b=(*p)+; / 把a0赋给b后, /p所指元素a0的值自增,即a0+=1 p=a,b=*(p+);/ 等同于p=a,b=*p+; p= / p所

10、指元素的值自增(a2+=1)后,赋给b,2020/8/8,27,当指针变量指向数组时,用指针变量操作数组的基本方法有2种: (1)以指针变量名代替数组名完成数组的操作; (2)直接通过指针变量完成对数组的操作。 这2种方法的区别在于:第1种方法,指针变量所指的位置不变,指针变量仍指向原来的地方;第2种方法,指针变量所指的位置将发生变化。,2020/8/8,28,例8-5 通过指针变量输出一维数组各元素的值及其地址。 算法分析: 通过循环语句遍历数组,在遍历的过程中以多种形式输出各元素的值及其地址。,2020/8/8,29,# include void main(void) int a3=1,3

11、,5,*p1=a,*p2=a; for (int i=0; i3; i+) coutaitp1itt *(p1+i)t *p2n; cout地址t ,2020/8/8,30,需要指出的是,上例中的指针变量是指向首元素的,当指针变量指向其它元素时,虽然也可以用指针变量来操作数组,但指针变量名已不能代替原数组名,它所代替的是指针变量所指位置开始的数组。 一般地,当指针变量p 指向数组a 中下标为 j的元素时(p=a+j或p= int n,t,*p1,*p2; coutn; p1=a; /p1指向数组的第1个元素 p2=a+10-n;/p2指向数组的倒数第n个元素 for (int i=0; in;

12、 i+) t=p1i; /方法一:以指针变量名代替数组名 p1i=p2i; p2i=t; ,2020/8/8,33,/*for (int i=0; in; i+,p1+,p2+) /方法二:直接使用指针变量 t=*p1; *p1=*p2; *p2=t; */ cout对调后的序列为:n; for(i=0;i10;i+) coutait; /输出对调后数组 coutn; ,2020/8/8,34,通过指针变量操作字符数组,1. 用字符型指针变量操作字符数组(字符串)的基本方法。 (1) 可以将一个字符数组的首地址(数组名)赋给一个字符类型的指针变量; (2) 可以将一个字符串赋给字符型指针变量(

13、实质上是先在内存中存放一个字符串,然后再把该字符串的首地址赋给该指针变量);,2020/8/8,35,(3) 字符串处理函数中,可以用字符型指针变量代替字符串; (4) 可通过字符型指针变量实现对该指针变量所指的内存空间进行输入、输出处理,输入字符型指针变量实质上是把输入的内容存放到该指针变量所指的内存区域,输出字符型指针变量则是从该指针变量所指位置开始输出对应内存中的内容,直至字符串结束标志。,2020/8/8,36,如:char s50=“asdfgh”,*s1=s,*s2,*s3= “C+ Program !”, *s4; s2 =“This is a string !”; / s3是初

14、始化,s2是先定义后赋值 strcpy(s,s2); / A行,s中内容为“This is a string !” s3=s+2; cins3; / B行,输入字符个数不能超过47个(不含结束标志) /若输入“123”,则s中的内容变为“Th123” couts2;/ D行,编译时不报错,执行时报内存引用错误 cins4; / E行,编译时警告性错误,执行时报内存引用错误,2020/8/8,37,2. 用字符型指针变量操作字符数组(字符串)时应注意的问题。 (1) 使用前,字符型指针变量所指的区域必须确定; (2) 注意指针变量所指的区域大小必须满足要求; (3) 注意字符型指针变量与字符数组

15、的差异; (4) 注意字符串的结束标志。,2020/8/8,38,例8-7 通过字符型指针变量拼接字符数组,如把“abcd”和“1234” 拼接成“abcd1234”。 算法分析: (1) 先使指针变量ptr1和ptr2分别指向数组str1和str2(B行); (2) 移动ptr1到str1的结束标志处(C行); (3) 通过ptr2对str2遍历,在遍历的过程中,把ptr2所指的字符逐一地对应地赋给ptr1所指的字符(D处循环); (4) 拼接完成后,给str1添加字符串的结束标志。,2020/8/8,39,#include void main() char str140,str220,*p

16、tr1,*ptr2; cout请输入字符串1:; cin.getline(str1,20);/A 输入字符串 cout请输入字符串2:; cin.getline(str2,20); ptr1=str1; ptr2=str2;/B 初始化指针变量 while(*+ptr1); /C ptr1定位到字符串1结束标志处 while(*ptr2) /D 字符串2拼接到字符串1后 *ptr1=*ptr2; ptr1+,ptr2+; ,2020/8/8,40,*ptr1=0; /E 拼接完后置字符串结束符0 cout拼接后的字符串是:; coutstr1endl; 调试与运行: 请输入字符串1:abcd

17、请输入字符串2:1234 拼接后的字符串是:abcd1234,2020/8/8,41,8.3指针数组,指针数组的定义,如果一个数组的所有元素均是指针,则称该数组为指针数组。其定义格式如下: 类型 *数组名数组大小; 如:char *p10 ; /定义了一个字符型的指针数组,可以存放10个字符型的指针(地址),2020/8/8,42,通过指针数组操作一维数组和二维数组,可以把一维数组每个元素的地址保存在指针数组中,也可以把二维数组每行元素的地址保存在指针数组中,然后通过指针数组来操作一维和二维数组。,2020/8/8,43,例8-8 通过指针数组输出一维数组和二维数组。 算法分析: (1)把一维

18、数组a中每个元素的地址依次保存在指针数组p中; (2)把p中地址对应的元素一一输出; (3)类似地,也可以用指针数组来操作二维数组。,2020/8/8,44,#include void main() int a5=1,2,3,4,5,*p5; for(int i=0;i5;i+) /A 将各元素地址保存在指针数组中 pi=,2020/8/8,45,int b56=1,2,3,4,5,6,7,8,9,10,11,12,13; for(i=0;i5;i+) pi=bi; /E 操作二维数组 cout二维数组为:n; for(i=0;i5;i+) for(int j=0;j6;j+) coutpij

19、t;/F coutn; ,2020/8/8,46,通过指针数组和指向指针的指针变量操作系列字符串,设有二维字符数组定义如下: char s510=“String1”,“String2”,“String3”,“String4”,“String5”; 数组s 中的每个元素s0、s1、s2、s3和s4都是一个一维的字符数组(字符串),也是一个字符型的指针,可以把它们存放到一个指针数组中。,2020/8/8,47,如: char *str5=s0,s1,s2,s3,s4; 定义指针变量p,char *p=str;p 是指向指针的指针变量 。通过下列语句可以方便地实现二维字符数组的输出: for(int

20、 i=0;i5;i+) cout*p+n;,2020/8/8,48,*p= stri,图3-1 用指针数组和二级指针处理系列字符串,2020/8/8,49,例8-9 设计一个程序,实现系列字符串按字母顺序排序。,2020/8/8,50,算法分析: (1) 把系列字符串保存在指针数组中; (2) 用直接选择排序法对系列字符串进行排序; (3) 直接选择排序法: 第1次循环(i=0),把最小(升序)或最大(降序)的数据放在第1位;第2次循环(i=1),把次小或次大的数据放在第2位;以此类推,直到所有数据排序结束。,2020/8/8,51,#include #include void main()

21、char *week =Monday,Tuesday, Wednesday,Thursday,Friday, Saturday,Sunday; char *p1,*p2=week; int i,j;,2020/8/8,52,for(i=0;i0) p1=weeki; weeki=weekj; weekj=p1; cout按字母顺序排序为:n; for(i=0;i7;i+) cout*p2+n; /输出排序后各字符串 ,2020/8/8,53,8.4指针和函数,指针作为函数的参数,将指针作为函数的参数时,传递给函数的是某一个变量的地址,称为地址传递。 指针值和指针所指向的数据均可作为函数的输入参

22、数。也可将指针所指向的数据作为函数的输出参数。,例8-10:实现两个数据的交换。,2020/8/8,54,#include void swap(int *p1,int *p2) int temp; temp=*p1; *p1=*p2; *p2=temp; void main(void) int a,b; coutab; coutna=a,b=bn; swap(,执行后输出:a=100,b=200 a=200,b=100,2020/8/8,55,2020/8/8,56,若将该例中的swap()函数改为: void swap1(int x,int y) /指针参数改为整型变量 int t; t=x

23、;x=y;y=t; 主函数中swap( for(i=0;i*(p+j) temp=*(p+i); *(p+i)=*(p+j); *(p+j)=temp; ,2020/8/8,59,void sort2(int *p,int n) int i,j,temp; for(i=0;ipj) temp=pi; pi=pj; pj=temp; ,void sort3(int b,int n) int i,j,temp; for(i=0;ibj) temp=bi; bi=bj; bj=temp; ,2020/8/8,60,void main(void) int a6=4,67,3,45,34,78,*poi

24、nt; int b6=4,67,3,45,34,78; int c6=4,67,3,45,34,78; point=c; sort1(a,6); sort2(b,6); sort3(point,6); for(point=a;pointa+6;) cout*point+t; coutn; for(point=b;pointb+6;) cout*point+t; coutn; for(point=c;pointc+6;)cout*point+t; coutn; ,2020/8/8,61,执行后输出: 3 4 34 45 67 78 3 4 34 45 67 78 3 4 34 45 67 78,

25、2020/8/8,62,多维数组作函数参数下列三种情况相同: (1)多维数组作形参,实参为多维数组名; (2)将多维数组作为一维数组处理,一维数组或一级指针作一个形参,另一形参为数组元素的个数,实参为数组的起始地址;,2020/8/8,63,例8-12:设计一程序,求二维数组的平均值。,#include /average1、average2作用相同 float average1(float *p,int n) /将二维数组作一维数组处理,第一个参数为 /一级指针,对应第0行第0列元素的地址,第 /二个参数为二维数组中元素的个数 float sum=0; int i; for(i=0;in;i+

26、)sum+=*p+; return sum/n; ,2020/8/8,64,float average2(float p4,int n) /第一个参数为二维数组,对应的实参为数组名 /score,第二个参数为二维数组的行数 float sum=0; int i,j; for(i=0;in;i+) for(j=0;j4;j+)sum+=pij; return sum/(n*4); ,2020/8/8,65,void main(void) float score34=65,67,70,60, 80,87,90,81,90,99,100,98; cout平均值= average1(*score,12

27、)n; cout平均值= average2(score,3)n; ,2020/8/8,66,执行后输出:平均值=82.25 平均值=82.25 平均值=82.25,2020/8/8,67,函数返回值为指针的函数,用return可返回一个值或不返回值,但需返回多于一个值时,要通过函数的参数来实现。另外还可返回一个指针,指针可指向任一已定义的类型数据。,一般定义格式: 类型符 *函数名(参数表) 如:int *fp(char); /函数fp返回一个指向整型的指针,2020/8/8,68,例8-13:设计一程序,将输入的字符串按逆序输出。,分析:用字符型指针变量p1指向原字符串的第0个字符,用指针变

28、量p2指向最后一个字符,将p1和p2所指的字符交换,p1向后移一位,p2向前移一位,继续。,2020/8/8,69,#include char *flip(char *ptr) char *p1,*p2,temp; p1=p2=ptr; /使p1和p2指向字符串的第0个位置 while(*p2+); /执行后p2指向字符串结束字符后面一个位置 p2-=2; /使p2指向字符串的最后一个字符的位置 while(p1p2) /将p1所指的与p2所指的交 /换,并使p1向后移一位,p2向前移一位 temp=*p2;*p2-=*p1; *p1+=temp; return ptr; ,2020/8/8,

29、70,void main(void) char str200; cout输入一个字符串:; cin.getline(str,199); coutstrn; coutflip(str)n; ,若输入字符串: Computer Department. 则输出: .tnemtrapeD retupmoC,2020/8/8,71,例8-14:输入两个字符串,设计一程序,把这两个字符串拼成一个新的字符串,然后输出这三个字符串,字符拷贝和拼接的函数自己设计。,2020/8/8,72,#include char *copy(char *to,char *from) char *p=to; while(*to

30、+=*from+); return p; char *stringcat(char *to,char *from) char *p=to; while(*to+); to-; while(*to+=*from+); return p; ,2020/8/8,73,void main(void) char s1100,s2100,s3200; cout输入第一个字符串s1=; cin.getline(s1,99); cout输入第二个字符串s2=; cin.getline(s2,99); copy(s3,s1); cout将s1拷贝到s3中后,s3= s3n; cout将s2拼接到s1后的字符串为

31、: stringcat(s3,s2)n; ,2020/8/8,74,若输入字符串: C+ Program和ming Socre. 则输出: s1=C+ Program s2=ming Score. 将s1拷贝到s3中后,s3=C+Program 将s2拼接到s1后的字符串为: C+Programming Score.,2020/8/8,75,指向函数的指针,虽然函数不是变量,仍占存储空间,此空间的首地址函数入口地址称为函数的指针,若指针变量的值为一个函数的入口地址,则称它为指向函数的指针变量。 (1)定义格式 存储类型 数据类型 (* 函数指针名)(参数表) 如:int (*fp) ( cha

32、r ); /fp为一函数指针, 此函数的返回值为int,参数为char int (*fp)(float,float); / fp为指向int型函数的指针变量,2020/8/8,76,注意:“*指针变量”外的括号不能缺,否则成了返回指针值的函数。,(2)赋值 函数名代表该函数的入口地址。因此,可用函数名给指向函数的指针变量赋值。 指向函数的指针变量函数名; 注意:函数名后不能带括号和参数,且与该指针变量具有相同的返回值类型和相同参数(个数与顺序均一致)。,2020/8/8,77,(3)调用格式 (*函数指针变量) (实参表) 或 函数指针变量 (实参表),如:float f(float); fl

33、oat (*fp1)(void); float *(*fp2)(float *,float *); float *f2(float *,float *); fp1=f; /错误,变量类型不同 fp2=f2; /正确,2020/8/8,78,8.5new和delete运算符,C+中的new运算符可根据对象的类型,自动决定其大小,动态地分配空间,返回的是内存地址, 可赋给一个指针, 如: int n; cinn; int *pi; /定义一个指针变量 pi=new intn; /分配内存地址给 pi int *pp,a=9; pp= /OK delete p; /OK delete p; /危险!

34、,2020/8/8,83,例8-15:设计一程序,实现动态内存空间分配。,#include void main(void) int *p1; float *fp1; char *cp1; p1=new int; /动态地分配一个存放一个整数的内 /存空间,使p1指向该单元,2020/8/8,84,fp1=new float(2.5); /动态分配一个 /存放实数的内存空间,并初始化为2.5 cp1=new char; /分配一个存放一个 /字符的内存空间,cp1指向该空间 *cp1=A; *p1=25; cout*p1=*p1n; cout*fp1=*fp1n; cout*cp1=*cp1n;

35、 delete p1; /将用new分配的内存空间归还给系统 delete fp1; delete cp1; ,2020/8/8,85,执行后输出: *p1=25 *fp1=2.5 *cp=A,2020/8/8,86,使用new和delete运算符应注意的事项,1. new所分配的存储空间的初值不确定,使用前应初始化。 2. 一般应检验new分配的空间是否分配成功,若失败应终止程序或作出错处理。如: float *p; p=new float 1000; if(p= =0) cout“动态分配内存不成功,终止程序的执行!n”; exit(3); 3. 动态分配存放数组的内存空间,或为结构体分配

36、内存空间时,不能在分配空间时进行初始化。如: int *pi; pi=new int 10(1,2,3,4,5,6,7,8,9); /错误,2020/8/8,87,4. 若new运算符计算的指针类型与赋值运算符左操作数类型不一致时,要进行强制转换。如: float (*p1)10,(*p2)20; p1=new float20; /错误。因p1是用于指向二维数组的指 /针,而new运算的结果为一维数组的指针 而 p1=(float (*)10)new float10;/正确。进行了强制类型转换 或 p1=new float110; /正确。分配二维数组的内存空间 又如: p2=new floa

37、t1020; /正确。分配10行,每行20个元素的二维数组 int *p3; p3=new int1020; /错误 而 p3=(int *)new int1020; /正确 或 p3=new int10*20; /正确,2020/8/8,88,5. 用new分配的内存空间指针值应保存,以便用delete归还,否则出错。如: float *fp,i; fp=new float; *fp=24.5; fp= int 输出的值为5 。 特别提示:必须是对一个已存在变量的引用。,2020/8/8,92,2、引用举例 例8-16 引用类型变量运算。 要求:掌握引用类型变量的使用方法。,2020/8/8

38、,93,编程实现: #include void main(void) int a=10;/A行 int ,2020/8/8,94,调试与运行: 输出: a=10 b=10 a=20 b=20 a=30 b=30 说明: 变量与引用类型的变量是同一个变量的两个不同名字。 对任何一个改变其值,另一个也同时改变。,2020/8/8,95,注:(1)定义引用类型变量时,要初始化。初始化变量类型 要与引用类型变量的类型相同。如: float x; int t=*p1;*p1=*p2;*p2=t; ,2020/8/8,99,void swap2(int ,2020/8/8,100,若输入x、y的值为300

39、、400,a、b的值为100、200,则输出: x=400 y=300 a=200 b=100,例8-18 分析以下程序的执行结果。 #include int a=20;/A int fun(int *a, int ,void main(void) int a=10,b=1,c=1;/D coutfun( ,调试与运行: 35 73 74 112 113,2020/8/8,103,8.7简单链表及其应用,链表概述,链表是指将若干个同类型的结构体类型数据按一定的原则连接起来。,头指针,struct node char name20; int age; node *next; ;,2020/8/8

40、,104,链表的一般形式,(1)头指针变量head指向链表的首结点。 (2)每个结点由2个域组成: 1)数据域存储结点本身的信息。 2)指针域指向后继结点的指针。 (3)尾结点的指针域置为“NULL(空)”,作为链表结束的标志。,2020/8/8,105,对链表的基本操作有:创建、检索(查找)、插入、删除和修改等。 (1)创建链表是指,从无到有地建立起一个链表,即往空链表中依次插入若干结点,并保持结点之间的前驱和后继关系。 (2)检索操作是指,按给定的结点索引号或检索条件,查找某个结点。如果找到指定的结点,则称为检索成功;否则,称为检索失败。 (3)插入操作是指,在结点ki-1与ki之间插入一

41、个新的结点k,使线性表的长度增1,且ki-1与ki的逻辑关系发生如下变化: 插入前,ki-1是ki的前驱,ki是ki-1的后继;插入后,新插入的结点k成为ki-1的后继、ki的前驱。,链表的操作,2020/8/8,106,2020/8/8,107,(4)删除操作是指,删除结点ki,使线性表的长度减1,且ki-1、ki和ki+1之间的逻辑关系发生如下变化: 删除前,ki是ki+1的前驱、ki-1的后继;删除后,ki-1成为ki+1的前驱,ki+1成为ki-1的后继。,2020/8/8,108,例8-19:链表的基本操作。,包括: (1)建立一条无序链表; (2)输出链表上各结点的数据; (3)删

42、除链表上一个结点; (4)建立一条有序链表,输出链表上的各结点的数据。,结点的结构如下: struct node int data; node *next; ;,2020/8/8,109,建立一条无序链表,函数如下:,node *create( ) node *p1,*p2,*head; int a; head=0; /建立空链表 couta;,2020/8/8,110,while(a!=-1) p1=new node; /申请空间 p1-data=a; /给新空间赋值 if(head=0) /若为空表 head=p1;p2=p1; /将新结点插入 else /非空表 p2-next=p1;p

43、2=p1; /将新结点插入 cina; if(head)p2-next=0; /最后一个结点的指针域赋0 return(head); ,2020/8/8,111,输出链表上各个结点的值,函数如下:,void Print(const node *head) const node *p; p=head; coutdatanext; /p指向下一个结点 coutn; ,2020/8/8,112,删除链表上具有指定值的一个结点,函数如下:,node *Delete_one_node(node *head, int num) node *p1,*p2; if(head=NULL) /链表空,不做 cou

44、t链表为空,无结点可删!n; return(NULL); ,2020/8/8,113,if(head-data=num) p1=head; /若要删首结点,则将p1指向第一个结点 head=head-next; /head指向第二个结点 delete p1; /删除p1所指结点 cout删除了一个结点!n; ,2020/8/8,114,else p2=p1=head; while(p2-data!=num /p2指向后一个结点 ,2020/8/8,115,if(p2-data=num) p1-next=p2-next; /与下一行一起删除p2所指结点 delete p2; cout删除了一个结

45、点!n; else coutnum 链表上没有找到要删除的结点!n; /没有要删的结点 return(head); ,2020/8/8,116,释放链表的结点空间。函数如下:,void deletechain(node *h) node *p1; while(h) p1=h; /与下一行一起完成取下一个结点的工作 h=h-next; delete p1; /删除p1所指结点 ,2020/8/8,117,将一个结点插入有序链表仍保持有序。函数如下:,node *Insert(node *head,node *p) node *p1,*p2; if(head=0) head=p; /空表时使hea

46、d指向p p-next=0; /链表尾指针为0 return(head); ,2020/8/8,118,if(head-data=p-data) /p所指结点插入首部 p-next=head; /head所指向的链表接在p之后 head=p; /head指向新的链表首部 return(head); p2=p1=head; while(p2-next ,2020/8/8,119,if(p2-datadata) /插入到最后 p2-next=p; p-next=0; else /将p所指结点插入到p1与p2之间 p-next=p2; p1-next=p; return(head); ,2020/8

47、/8,120,建立一条有序链表。函数如下:,node *Create_sort(void) node *p1,*head=0; int a; couta; while(a!=-1) p1=new node; p1-data=a; head=Insert(head,p1); cina; return(head); ,2020/8/8,121,完成链表处理的完整程序如下:,#include struct node int data; node *next; ;,2020/8/8,122,node *Create(void) /产生一条无序链表 node *p1,*p2,*head; int a;

48、head=0; couta; while(a!=-1) p1=new node; p1-data=a; if(head=0) /插入链表的首部 head=p1;p2=p1; else /插入链表尾 p2-next=p1;p2=p1; cina; if(head)p2-next=0; return(head); ,2020/8/8,123,void Print(const node *head) /输出链表上各结点的数据 const node *p; p=head; coutdatanext; coutn; ,2020/8/8,124,node *Delete_one_node(node *head,int num) /删除一个结点 node *p1,*p2; if(head=0) coutdata=num) /删除链表首结点 p1=head; head=head-next; delete p1; cout删除了一个结点!n; ,2020/8/8,125,else p1=head; p2=head-next; while(p2-da

温馨提示

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

评论

0/150

提交评论