专业课参考-语言程序设计_第1页
专业课参考-语言程序设计_第2页
专业课参考-语言程序设计_第3页
专业课参考-语言程序设计_第4页
专业课参考-语言程序设计_第5页
已阅读5页,还剩35页未读, 继续免费阅读

付费下载

下载本文档

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

文档简介

链表:将数据串起来共74页第2

页用户自定义类型

标准(基本)类型(如int、char、long、double等):系统已经定义好的数据类型,用户可以直接使用,无须定义。

自定义类型:用户可根据实际情况,自己定义的、新的数据类型。 可以根据自己的需要对已有的数据类型重新命名:用typedef

语句定义与已有的数据类型等价的新的类型说明符。用typedef定义数据类型共74页第3

页typedef语句的一般形式typedef

已定义的类型新的类型说明符实例

typedef

intINTEGER;

typedef

floatREAL;

typedef

int*POINTI; 下述语句等价:

INTEGERi,j;<==>inti,j;

REALpai;

<==>floatpai;POINTIp;<==>

int*p;用typedef定义数据类型共74页第4

页例C10-18.C:改写“用结构变量求解两个复数之积”的程序。 typedefintINTEGER;

typedefstructcomplx{/*定义COMP*/

INTEGERreal,im;

}COMP; main() {staticCOMPza={3,4},zb={5,6};

COMPz,cmult(); voidcpr(); z=cmult(za,zb);cpr(za,zb,z); }用typedef定义数据类型共74页第5

页

COMPcmult(COMPza,COMPzb)/*返回COMP*/ {COMPw; w.real=za.real*zb.real-za.im*zb.im; w.im=za.real*zb.im+za.im*zb.real; return(w); } voidcpr(COMPza,COMPzb,COMPz) {printf("(%d+%di)*(%d+%di)=",za.real,za.im,zb.real,zb.im); printf("(%d+%di)\n",z.real,z.im); }用typedef定义数据类型共74页第6

页常见问题 如何对超长整数进行四则运算?如何保存一个任意长度的整数?

如何说明不定长度的数组? intn; scnaf("%d",&n); intarray[n];

数组:不能进行动态说明。解决方案

采用可变长的动态结构保存不定长数据。链表基础-提出问题共74页第7

页链表定义 一种简单、常见的动态结构,通过指针(链)将一组保存信息的结点链接在一起。结点定义 结点包括两部分:信息和链接结点的指针。 例如:使用结点描述一个学生的信息(姓名)

structnode{

char

name[20]; /*信息*/

structnode

*link; /*

指针*/ };链表基础-定义与表示共74页第8

页链表组成

指向链表表头结点的指针(表头指针,头指针)

表头结点(链表的第一个结点,不保存信息)

表结点(数据结点,也称为结点,保存信息)链表的图示表示NULL头指针头结点数据结点1数据结点n数据结点i数据结点2链表基础-定义与表示........共74页第9

页定义结点的结构,说明表头指针 根据需要保存的信息来定义结点的结构。 定义描述学生(姓名/住址/电话)的结点:

typedefstructnode

{

charname[20],address[20],phone[15];

structnode*link; //

指针

}

NODE

; //定义结点

NODE

*

head;

//说明头指针head

typedefstructnode*PNODE;

PNODEhead; //说明头指针head链表基础-建立链表的基本方法共74页第10

页建立表头结点:申请存储空间

NODE*

p,*head;

p=(

NODE*)malloc(sizeof(NODE));

//申请表头结点

p->link=NULL; //将表头结点的link置为NULL head=

p; //head指向表头结点pNULL表头结点头指针head空链表p链表基础-建立链表的基本方法 head=(

NODE*)malloc(sizeof(NODE));

head->link=NULL;

//将表头结点的link置为NULL共74页第11

页从表头开始将数据结点插入到链表中(插入第一个数据结点)

NODE*

p;

p=(NODE*)malloc(sizeof(NODE));//申请结点

gets(p->name); //数据存入结点

p->link=head->link; //①修改结点指针 head->link=

p; //②插入到表头NULL头指针表头结点headp数据结点nameNULL链表基础-建立链表的基本方法共74页第12

页在链头插入数据结点(插入下一个数据结点)

p=(NODE*)malloc(sizeof(NODE));

gets(p->name);

p->link=head->link;//①修改结点指针 head->link=

p;//②插入到表头p头指针表头结点head数据结点name1NULL新数据结点xname2链表基础-建立链表的基本方法头指针表头结点headname1NULLname2共74页第13

页将结点插入到链表的链头(程序)

调用create函数时,已经建立好表头结点。 head=(

NODE*)malloc(sizeof(NODE));

head->link=NULL;//head指向头结点 voidcreate(NODE*

head,

intn)//建n个结点

{ NODE*p;

for(;n>0;n--

) {

p=(NODE*)malloc(sizeof(NODE)); gets(p->name);

p->link=head->link;//①修改结点指针 head->link=

p;//②插入到表头 }

}链表基础-建立链表的基本方法共74页第14

页访问链表中全部数据结点 voidoutput(NODE*head)

{NODE*p;

p

=

head->link; //指向第一个数据结点

while

(p!=NULL

)

{

puts(p->name); //输出结点数据

p=p->link;

//p指向下一结点 }

}NULL头指针表头结点head链表基础-访问链表全部结点头指针表头结点head数据结点1name数据结点nnameNULL....共74页第15

页求链表长度:链表中所包含的数据结点的数量。 intlength(NODE*head) {intlen;

NODE*p; for(len=0,p=head->link;p!=NULL;++len)

p=p->link;//p指向下一个结点

return(len); }链表基础-求链表长度NULL头指针表头结点head头指针表头结点head数据结点1name数据结点nnameNULL....^ppp^p....共74页第16

页在第i

个结点的后面插入新结点:基本原理定位:指针q

指向第i

个结点,指针

p

指向需要插入的结点headD3D2D1D0^表头结点数据结点数据结点i数据结点数据结点Dpqx链表基础-插入操作链接后面指针:p->link=q->link;链接前面指针:q->link=p;共74页第17

页在第i

个结点的后面插入新结点p voidinsert_node(NODE*head,

NODE*p,

inti)

{NODE*

q;intn=0; for(q=head;

n<i&&

q->link!=NULL;++n

)

q

=

q->link; //①定位

p->link=q->link; //②链接后面指针

q->link=p; //③链接前面指针

}特殊情况:空表插入/插入位置超过链表长度^head表头结点Dpq^链表基础-插入操作共74页第18

页删除第i

个结点:基本原理定位:指针

q

指向第i-1

个结点,指针

p

指向被删除的结点headD3D2D1D0^头结点数据结点数据结点i-1数据结点i数据结点qpx链表基础-删除操作摘链:q->link=p->link;释放p结点:free(p)共74页第19

页在链表中删除第i

个结点(程序)

voiddelete_node(NODE*head,inti)

{NODE*q,

*p;intn=0;

for

(q=head;

n<i-1&&

q->link!=NULL;++n

)

q=q->link; //①定位

if

(i>0&&q->link!=

NULL

){ p=q->link; //p指向被删除结点

q->link=p->link; //②摘链

free(p); //③释放p结点

}

}特殊情况

指定位置i超长;

删成空链表

head表头结点^数据结点qp^x链表基础-删除操作共74页第20

页head-1DnD1D0^表头结点数据结点数据结点数据结点数据结点headDnD1D0^数据结点数据结点数据结点数据结点数据结点headDnD1D0数据结点数据结点数据结点数据结点数据结点head-1DnD1D0表头结点数据结点数据结点数据结点数据结点有表头结点的单向链表无表头结点的单向链表有表头结点的单向环表无表头结点的单向环表链表基础-常见形式共74页第21

页约瑟夫问题 这是十七世纪的法国数学家加斯帕在《数目的游戏问题》中讲的一个故事:15个基督教徒和15个异教徒在海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一个圆圈,从第一个人开始依次报数,每数到第9个人就将他扔入大海,如此循环进行直到仅余15人为止。问怎样排法,才能使每次投入大海的都是异教徒。算法分析与设计 定义一个结构,表示船上每一个人的状态。成员包括每个人的下一个相邻的人编号和是否被扔下海的记录。

structnode{ intnextp; /*指向下一个人的指针*/ intno_out; /*是否被扔下海的标记。1:船0:海*/ }link[31];§10-8链表基础-举例共74页第22

页23...10...i+1i+2...2930111...1...11...111link[0]link[30]link[i]link[9]数组下标j30报数计数器k0被扔下海的人数i023...10...i+1i+2...2930111...0...11...111link[0]link[30]link[i]link[9]j11k9i1§10-8链表基础-举例共74页第23

页 main() { inti,j,k; printf(“Theoriginalcircleis”); for(i=1;i<=30;i++) /*初始化数据*/ { link[i].nextp=i+1;link[i].no_out=1; } link[30].nextp=1;

j

=30;/*j:指向处理完的数组元素,从开始link[j]计数*/ for(i=0;i<15;i++) /*i扔下海的人数计数器*/ { for(k=0;;) /*报数计数器*/ if(k<9) { j=link[j].nextp;

k+=link[j].no_out; } elsebreak;

link[j].no_out=0; /*将该人扔下海,标志置0*/ } for(...)... /*输出结果*/ }§10-8链表基础-举例例C6_8001共74页第24

页用链表的方法对约瑟夫问题进行编程算法分析与设计

用链表解决约瑟夫问题,首先定义链表数据结构

structnode{ intno_out;

structnode*next; };1111...head表头结点数据结点数据结点数据结点数据结点§10-8链表基础-举例共74页第25

页 main() { inti,j,k; structnode*head,*p;

head=(structnode*)malloc(sizeof(structnode));

head->next=head; for(i=1;i<30;i++) /*初始化数据*/ { p=(structnode*)malloc(sizeof(structnode));

p->next=head->next;

p->no_out=1;head->next=p; } head->no_out=1;

p=(structnode*)malloc(sizeof(structnode));

p->next=head;

head=p;/*j:指向处理完的数组元素,从开始link[j]计数*/ for(i=0;i<15;i++) /*扔下海的人数计数器*/ { for(k=0;;) /*报数计数器*/ if(k<9) {p=p->next;k+=p->no_out; } elsebreak; p->no_out=0; /*将该人扔下海,标志置0*/ } for(...)... /*输出结果*/ }§10-8链表基础-举例例C6_8002共74页第26

页约瑟夫问题 十七世纪法国数学家加斯帕在《数目的游戏问题》中讲的一个故事:15个基督教徒和15个异教徒在海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是30个人围成一个圆圈,从第1个人开始依次报数,每数到第

9

个人就将他扔入大海,如此循环直到仅余15

人为止。 问人员应该怎样安排,才能使每次投入大海的都是异教徒。链表基础-举例共74页第27

页用链表的方法对约瑟夫问题进行编程算法分析与设计

首先定义链表数据结构

structnode{ intno;

structnode*next; };期望建立的原始链表形式122930...head表头数据结点数据结点数据结点数据结点链表基础-举例共74页第28

页main(){ inti,k;structnode*head,*p,*q; head=(structnode*)malloc(sizeof(structnode)); head->no=-1; head->next=head;链表基础-举例-1122930...head表头数据结点数据结点数据结点数据结点-1head表头 for(i=30;i>0;i--)

{

p=(structnode*)malloc(sizeof(structnode)); p->no=i; p->next=head->next; head->next=p; }30pxp29p共74页第29

页 while(p->next!=head)//链跳过表头结点 p=p->next;链表基础-举例-1122930...head表头数据结点数据结点数据结点数据结点-1122930...head表头数据结点数据结点数据结点数据结点p p->next=head->next; //p指向30-1122930...head表头数据结点数据结点数据结点数据结点pp共74页第30

页 for(i=0;i<15;i++)//15人出列

{

for(k=1;k<9;k++)//报数到9为止 p=p->next; q=p->next;//p的下一个结点出列 p->next=q->next;//跳过要出列的结点 printf("%3d",q->no);//q结点的编号 free(q);//释放q结点 }链表基础-举例-1122930...head表头数据结点数据结点数据结点数据结点p共74页第31

页main(){ inti,k;structnode*head,*p,*q; head=(structnode*)malloc(sizeof(structnode)); head->no=-1; head->next=head; for(i=30;i>0;i--)/*生成循环链表*/ { p=(structnode*)malloc(sizeof(structnode)); p->next=head->next;p->no=i;head->next=p; } printf("\nTheoriginalcircleis:"); while(p->next!=head)/*循环链跳过表头结点*/ p=p->next; p->next=head->next; /*p指向30*/

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

{

for(k=1;k<9;k++) p=p->next; q=p->next;/*p的下一个结点是要出列的结点*/ p->next=q->next;/*循环链表跳过要出列的结点*/ printf(“%3d”,q->no);/*输出

q结点的编号*/ free(q);/*释放q

结点*/ }}链表基础-举例例C6_8003共74页第32

页已知一个有表头结点的单链表,结点结构为data/link,假设该链表只给出了头指针list。在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点(k为正整数)。若查找成功,算法输出该结点的data域的值,并返回1;否则,只返回0。要求:(1)描述算法的基本设计思想;(2)描述算法的详细实现步骤;(3)根据设计思想和实现步骤,采用程序设计语言描述算法(使用C或C++或Java语言实现),关键之处请给出简要注释。链表基础-举例共74页第33

页算法的基本设计思想假设链表的最后一个结点为倒数第1个结点。

对链表进行一遍扫描,用指针p和q分别指向两个结点,且保持指针p和指针q之间的“距离”(包含的结点数)为k,当p指向最后一个结点时,q指向的就是倒数第k个结点。链表基础-举例共74页第34

页算法的详细实现步骤假设表头指针为list,定义两个指针p和q:①初始化:距离计数器count=0;p=q=list->link,指向链表第1个数据结点;②若p非空,则执行③和④;否则转⑤;③如果count小于k,则count=count+1;否则q指向下一个结点;④p指向下一个结点,转步骤②;⑤若count等于k,则查找成功,输出该结点的data值,返回1;否则,查找失败,返回0。算法结束。链表基础-举例共74页第35

页intSearchRevk(pLinkListlist,intk){pLinkListp,q;intcount=0;//

距离计数器p=q=list->link;//p和q指向第一个数据结点while(p!=NULL){ if(count<k)count++; //计数器+1elseq=q->link; //q指向下一个结点p=p->link; //p指向下一个结点

}if(count==k)

{printf("%d\n",q->data); //

查找成功return1;

}elsereturn0; //

查找失败}链表基础-举例共74页第36

页用带头结点的单链表保存单词,当两个单词有相同的后缀时,可共享相同的后缀存储

温馨提示

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

评论

0/150

提交评论