版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、数据结构Data Structure2007年9月1学时数:48(32+16) 学 分: 2 教 材:严蔚敏等,数据结构(C语言版),清华大学出版社,1997年4月 (配题集) 参考书:1 殷人昆等,数据结构(用面向对象方法与C+描述),清华大学出版社,1999年7月。¥26 2 殷人昆等,数据结构习题解析,清华大学出版社,2002年4月。¥263 李春保,数据结构习题与解析(C语言篇),清华大学出版社,2001年1月。¥284 丁宝康等,数据结构自学考试指导,清华大学出版社, 2001年5月。¥232内 容 安 排实验:课内上机(16规定内容)+课外上机(24平时作业中编程题验证)3数据结构
2、课程的内容逻辑结构唯一存储结构不唯一运算的实现依赖于存储结构43.1 栈(Stack) 3.2 队列(Queue) 第三章 栈和队列1. 定义2. 逻辑结构3. 存储结构4. 运算规则5. 实现方式1. 定义2. 逻辑结构3. 存储结构4. 运算规则5. 实现方式51. 定义3.1 栈与线性表相同,仍为一对一( 1:1)关系。用顺序栈或链栈存储均可,但以顺序栈更常见只能在栈顶运算,且访问结点时依照后进先出(LIFO)或先进后出(FILO)的原则。关键是编写入栈和出栈函数,具体实现依顺序栈或链栈的存储结构有别而不同。3. 存储结构4. 运算规则5. 实现方式 2. 逻辑结构限定只能在表的一端进行
3、插入和删除运算的线性表。即栈顶基本操作有:建栈、判断栈满或栈空、入栈、出栈、读栈顶元素值,等等。6栈 是仅在表尾进行插入、删除操作的线性表。表尾(即 an 端)称为栈顶 /top ; 表头(即 a1 端)称为栈底/base例如: 栈 S= (a1 , a2 , a3 , .,an-1 , an )插入元素到栈顶的操作,称为入栈。从栈顶删除最后一个元素的操作,称为出栈。an称为栈顶元素a1称为栈底元素想一想:要从栈中取出a1,应当如何操作?强调:插入和删除都只能在表的一端(栈顶)进行!7Q1:堆栈是什么?它与一般线性表有什么不同? 堆栈是一种特殊的线性表,它只能在表的一端(即栈顶)进行插入和删除
4、运算。 与一般线性表的区别:仅在于运算规则不同。一般线性表 堆栈逻辑结构:1:1 逻辑结构: 1:1 存储结构:顺序表、链表 存储结构:顺序栈、链栈运算规则:随机存取 运算规则:后进先出(LIFO)“进”插入=压入=PUSH(an+1)“出”删除=弹出=POP(an)8 a1 a2 an顺序栈S aiQ2:顺序表和顺序栈的操作有何区别?表头表尾低地址高地址写入:Si= ai读出: e= Si压入(PUSH): Stop+=an+1弹出( POP) : e=S-top低地址高地址Si a1 a2 ai an 顺序表S an+1以线性表 S= (a1 , a2 , . , an-1 , an )为
5、例栈底base栈顶top前提:一定要预设栈顶指针top9栈不存在的条件: base=NULL;栈为空 的条件 : base=top;栈满的条件 : top-base=stacksize; a1 a2 an顺序栈S ai低地址高地址 an+1栈底base栈顶top10若入栈动作使地址向高端增长,称为“向上生成”的栈;若入栈动作使地址向低端增长,称为“向下生成”的栈; 对于向上生成的堆栈:入栈口诀:堆栈指针top “先压后加” : Stop+=an+1出栈口诀:堆栈指针top “先减后弹” : e=S-topQ3:什么叫“向上生成”的栈? “向下生成”又是何意?11Q4:为什么要设计堆栈?它有什么
6、独特用途?调用函数或子程序非它莫属;递归运算的有力工具;用于保护现场和恢复现场;简化了程序设计的问题。下面用4个例子来帮助理解堆栈:12void test(int &sum)int x;scanf(x);if(x=0)sum=0;elsetest(sum);sum+=x;printf(sum);断点地址入栈例1(严题集3.10)阅读下列递归过程,说明其功能。输入x10输入x50输入x2输入x3输入x4输出sum0输出sum0+x4输出sumx4+x3输出sum x4+x3 +x2输出sum x4+x3 +x2+x1注意:最先输入的数据 x1 最后才被累加程序功能:对键盘输入数据求和,直到输入0
7、结束13例2(严题集3.1)一个栈的输入序列为1,2,3,若在入栈的过程中允许出栈,则可能得到的出栈序列是什么?答:可以通过穷举所有可能性来求解: 1入1出, 2入2出,3入3出, 即123; 1入1出, 2、3入,3、2出, 即132; 1、2入,2出, 3入3出, 即231; 1、2入,2、1出,3入3出, 即213; 1、2、3入,3、2、1出, 即321;合计有5种可能性。14例3:一个栈的输入序列是12345,若在入栈的过程中允许出栈,则栈的输出序列43512可能实现吗?12345的输出呢?答:43512不可能实现,主要是其中的12顺序不能实现;12345的输出可以实现,每压入一数便
8、立即弹出即可。 思考:有无通用的判别原则?15例4:设依次进入一个栈的元素序列为c,a,b,d,则可得到出栈的元素序列是: )a,b,c,d )c,d,a,b )b,c,d,a )a,c,d,bA)、D)可以, B)、C)不行。讨论:有无通用的判别原则?有!若输入序列是 ,PjPkPi (PjPkM)上溢 else stop+=e;Push (B);Push (C);Push (D);toptoptoptop低地址LPush (A);高地址MBCD19顺序栈出栈操作例如从栈中取出BDCBAtoptopDCABDCBAtopDCBAtop低地址L高地址MD核心语句:Pop ( );顺序栈出栈函数
9、POP()status Pop( ) if(top=L) 下溢 else e=s-top; return(e); Pop ( );Printf( Pop () );20链栈的入栈操作和出栈操作(教材省略)(1) 链栈的构造方式以头指针为栈顶,在头指针处插入或删除.Node *st, *p;int m=sizeof(Node); 栈顶栈底栈也可以用链式结构来表示,用链式结构来表示的栈就是链栈st a1 a2an-1 annextdata链栈中每个结点由两个域构成:data域和next域,其定义为:typedef Struct SNode SElemType data; Struct SNode
10、* next; Node;21Push (SElemType e) p=(Node*)malloc(m); if(!p)上溢else p-data=e; p-link=st; st=p; Status Pop( ) if(st=NULL)下溢elsee=st-data;p=st;st=st-link; free(p); return(e); 链栈入栈函数链栈出栈函数插入表头从表头删除(2) 操作由此可以看出:一个链栈由其栈顶指针唯一指定 设st指向栈顶元素,则 st = NULL 表示栈空22链栈不必设头结点,因为栈顶(表头)操作频繁;链栈一般不会出现栈满情况,除非没有空间导致malloc分配
11、失败。链栈的入栈、出栈操作就是栈顶的插入与删除操作,修改指针即可完成。采用链栈存储方式的优点是,可使多个栈共享空间;当栈中元素个数变化较大,且存在多个栈的情况下,链栈是栈的首选存储方式。几点说明:23例1: 数制转换(十转N) 见教材P48 设计思路:用栈暂存低位值例2:括号匹配的检验见教材P49 设计思路:用栈暂存左括号例3 :表达式求值 -见教材P52 设计思路:用栈暂存运算符例4:汉诺(Hanoi)塔-见教材P55 设计思路:用栈实现递归调用栈的应用举例24例3 表达式求值 ( 这是栈应用的典型例子, 见P52 ) 这里,表达式求值的算法是 “算符优先法”。例如:编写算法,用栈实现表达式
12、3*(7 2 )求值。一个算术表达式是由操作数(x,y,z)和 算符(* ,/, + ,-,(,),# )组成.教材P53中表3.1给出了算符之间的优先级专为计算机处理而设计的表!表达式的起止符号(1) 表达式求值必须满足算术四则运算规则: a. 从左算到右 b. 先乘除,后加减 c. 先括号内,后括号外25(2) 算法思想:1)首先置操作数栈OPND为空栈,表达式的起始符#为运算符栈OPTR的栈底元素;2)依次读入表达式中的每个字符,若运算符是#或栈顶是#,结束计算,返回OPND栈顶值。 if(是操作数) 则PUSH( OPND,操作数); if(是运算符) 则与OPTR栈顶元素进行比较,按
13、优先级(规定详见P53表3.1)进行操作;为了实现算符优先算法,可以设定两个工作栈,OPND存放操作数或运算结果, OPTR存放运算符号。3)直到整个表达式求值完毕(当前读入的字符和OPTR栈的栈顶元素均为# ) if栈顶元素运算符,则退栈、按栈顶计算,将结果压入OPND栈。且该未入栈的运算符要保留,继续与下一个栈顶元素比较!26问:教材P53表3.1中,1和2哪个对应栈顶元素,哪个对应键盘输入值?答:根据P53Precede()函数可知, 1对应栈顶元素由表3.1可看出,右括号 ) 和井号 # 作为2时级别最低;由c 规则得出: * ,/, + ,-为1时的优先权低于(,高于) 由a规则得出
14、:(=) 表明括号内的运算已完成; # = # 表明表达式求值完毕。附:27表达式求值过程的描述:OPTROPNDINPUTOPERATE3*(7-2)#Push(opnd,3)#*(7-2)#3#Push(optr,*)#,*3(7-2)#Push(optr,()#,*,(37-2)#Push(opnd,7)#,*,(3,7-2)#Push(optr,-)#,*,(,3,72)#Push(opnd,2)#,*,(,3,7,2)#Operate(7-2)#,*,(3,5)#Pop(optr)#,*3,5#Operate(3*5)#15#GetTop(opnd)3*(7 2 )28Status
15、EvaluateExpression( OperandType &result) InitStack(OPND); InitStack(OPTR);Push(OPTR ,#);c=getchar(); while(c!=#)&(GetTop(OPTR)!=#) if (!In(c,OP) Push(OPND,c); c=getchar(); else switch(precede(GetTop(OPTR) , c) case : Pop(OPTR ,theta); Pop(OPND,b);a=Pop(); Push(OPND, Operate(a, theta,b) ;break; ; /sw
16、itch /while result=GetTop(OPND);/EvaluateExpressionOperate=a bC是操作符吗?运算符与栈顶比较并查3.1表29例4 汉诺( Hanoi)塔传说在创世纪时,在一个叫Brahma的寺庙里,有三个柱子,其中一柱上有64个盘子从小到大依次叠放,僧侣的工作是将这64个盘子从一根柱子移到另一个柱子上。分析: 设三根柱子分别为 x, y, z , 盘子在 x 柱上,要移到 z 柱上。1、当 n=1 时,盘子直接从 x 柱移到 z 柱上;2、当 n1 时, 则: 设法将 前 n 1 个盘子 从 x 移到 y 柱上(借助z),则 盘子 n 就能从 x
17、移到 z 柱上; 再设法把n 1 个盘子 从 y 移到 z 柱上(这又是一个与原来相同的问题,只是规模少了) 。x y znn 1移动时的规则: 每次只能移动一个盘子; 只能小盘子在大盘子上面; 可以使用任一柱子。当工作做完之后,就标志着世界末日到来。30Void Hanoi ( int n, char x, char y, char z ) /将n个编号从上到下为1n的盘子从x柱,借助y柱移到z柱 if ( n = = 1 ) move ( x , 1 , z ) ; /将编号为1的盘子从x柱移到z柱 else /将n-1个编号从上到下为1n-1的盘子从x柱,借助y柱移到z柱 Hanoi (
18、 n-1 , x , z , y ) ; move ( x , n, z) ; /将编号为n的盘子从x柱移到z柱 /将n-1个编号从上到下为1n-1的盘子从y柱,借助x柱移到z柱 Hanoi ( n-1 , y , x , z ); /Hanoi程序设计如下:谁能画出P57-58图3.7所示Hanoi塔的递归函数运行示意图?313.1 栈(Stack) 第三章 栈和队列3.2 队列(Queue)1. 定义2. 逻辑结构3. 存储结构4. 运算规则5. 实现方式1. 定义2. 逻辑结构3. 存储结构4. 运算规则5. 实现方式323.2 队列与线性表相同,仍为一对一关系。顺序队或链队,以循环顺序
19、队更常见。只能在队首和队尾运算,且访问结点时依照先进先出(FIFO)的原则。关键是掌握入队和出队操作,具体实现依顺序队或链队的不同而不同。存储结构运算规则实现方式 逻辑结构只能在表的一端进行插入运算,在表的另一端进行删除运算的线性表。基本操作:入队或出队,建空队列,判队空或队满等操作。尾部插入首部删除队列定义33队列 (Queue)是仅在表尾进行插入操作,在表头进行删除操作的线性表。它是一种先进先出()的线性表。例如:队列 Q= (a1 , a2 , a3 , .,an-1 , an )在队尾插入元素称为入队;在队首删除元素称为出队。队首队尾问:为什么要设计队列?它有什么独特用途?离散事件的模
20、拟(模拟事件发生的先后顺序,例如 CPU芯片中的指令译码队列);操作系统中的作业调度(一个CPU执行多个作业);3. 简化程序设计。答:34队的实现方式是本节重点,关键是掌握入队和出队操作。具体实现依存储结构(链队或顺序队)的不同而不同。1. 链队列 2. 顺序队队的抽象数据类型定义:ADT Queue数据对象:D=数据关系:R=基本操作: ADT Queue建队、入队或出队、判队空或队满等,教材P59-60罗列了9种基本操作。重点是循环顺序队35链队列类型定义: typedef struct QueuePtr front ; /队首指针 QueuePtr rear ; /队尾指针 LinkQ
21、ueue;结点类型定义: typedef Struct QNode QElemType data; /元素 Struct QNode *next; /指向下一结点的指针 Qnode , * QueuePtr ;关于整个链队的总体描述链队中任一结点的结构因简单而先介绍1.链队列36讨论:空链队的特征?Q(队尾)(队首)fronta1a2a3rearpfrontrear 怎样实现链队的入队和出队操作? 链队会满吗?front=rear一般不会,因为删除时有free动作。除非内存不足!入队(尾部插入):rear-next=S; rear=S;出队(头部删除):front-next=p-next;SD
22、链队示意图:完整操作函数见教材P62下37采用动态分配空间的形式顺序队类型定义:建队核心语句:q . base=(QElemType *)malloc(sizeof (QElemType )* QUEUE_MAXSIZE); /分配空间关于整个顺序队的总体描述#define QUEUE-MAXSIZE 100 /最大队列长度 typedef struct QElemType *base; /队列的基址 int front; /队首指针 int rear; /队尾指针 SqQueue顺序队中每个结点的结构描述在此省略,是QElemType类型。2.顺序队38Q(队尾)(队首)front a1 a
23、2 a3data a40.99rear 队列会满吗?极易装满!因为数组通常有长度限制,而其前端空间无法释放。 空队列的特征? 约定:front=rear队尾后地址入队(尾部插入): Qrear=e; rear+ ; 出队(头部删除): e=Qfront; front+; 讨论:假溢出!有缺陷 怎样实现入队和出队操作?核心语句如下:用base做数组名e顺序队示意图:39解决假溢出的途径采用循环队列答:在顺序队中,当尾指针已经到了数组的上界,不能再有入队操作,但其实数组中还有空位置,这就叫“假溢出”。问:什么叫“假溢出” ?如何解决?40a3a2a10123N-1rearfront循环队列(臆造)
24、新问题:在循环队列中,空队特征是front=rear;队满时也会有front=rear;判决条件将出现二义性!解决方案有三:使用一个计数器记录队列中元素个数(即队列长度);加设标志位,删除时置1,插入时置0,则可识别当前front=rear属于何种情况 人为浪费一个单元,则队满特征可改为front=(rear+1)%N;顺序队列a3a2a1frontrear 0 1 2 3 . .N-141队空条件 : front = rear (初始化时:front = rear )队满条件: front = (rear+1) % N (N=maxsize)队列长度(即数据元素个数):L=(Nrearfro
25、nt)% N J2 J3J1 J4 J5frontrear 实际中常选用方案3(人为浪费一个单元):即front和rear二者之一指向实元素,另一个指向空闲元素。 问3: 在具有n个单元的循环队列中,队满时共有多少个元素? N-1个6 问1:左图中队列maxsize N=?问2:左图中队列长度L=?542() rf ()(nfr)% n ()nrf () (nrf)% n要分析4种公式哪种最合理?当 r f 时(A)合理;当 r f 时(C)合理;答:综合2种情况,以(D)的表达最为合理例2:在一个循环队列中,若约定队首指针指向队首元素的前一个位置。那么,从循环队列中删除一个元素时,其操作是
26、先 移动队首指针取出元素,后。例1:数组n用来表示一个循环队列,f 为当前队列头元素的前一位置,r 为队尾元素的位置。假定队列中元素的个数小于n,计算队列中元素的公式为:43例3: 一循环队列如下图所示,若先删除4个元素,接着再插入4个元素,请问队头和队尾指针分别指向哪个位置? J2 J3J1 J4 J5front=1rear=0解:由图可知,队头和队尾指针的初态分别为front=1和rear=0。删除4个元素后f=5;再插入4个元素后,r=(0+4)%6=4 front=5J6 J5J7J8 J9rear=4rear=0front=544讨论:循环队列的基本操作如何实现?以建队、入队和出队三
27、种基本操作为例1)初始化一个空队列算法要求:生成一空队列算法操作:为队列分配基本容量空间 设置队列为空队列,其特征即: front=rear=0(也可为任意单元,如1,2,甚至-1 )45建队的完整算法:Status InitQueue ( SqQueue &q ) /初始化空循环队列 q q . base=(QElemType *)malloc(sizeof(QElemType)* QUEUE_MAXSIZE); /分配空间if (!q.base) exit(OVERFLOW);/内存分配失败,退出程序 q.front =q.rear=0; /置空队列 return OK; /InitQue
28、ue;46算法说明:向循环队列的队尾插入一个元素分 析:(1) 插入前应当先判断队列是否满? if ( q . rear + 1 ) % QUEUE_MAXSIZE )=q.front) return ERROR;(2)插入动作 q.base q.rear = e; q.rear = ( q . rear + 1 ) % QUEUE_MAXSIZE;2) 入队操作队列尺寸47Status EnQueue(SqQueue &q, QElemType e)/向循环队列 q 的队尾加入一个元素 e if ( (q.rear+1) % QUEUE_MAXSIZE = = q.front ) return ERROR ; /队满则上溢,无法再入队 q.base q.rear = e; /新元素e入队 q.rear = ( q . rear + 1 ) % QUEUE_MAXSIZE; /指针后移 return OK; / EnQueue;入队操作完整算法rear指针在元素入队后再加483)出队操作算法说明:删除队头元素,返回
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 采购项目规范性审核制度
- 采购餐厅管理制度
- 重庆采购专家回避制度
- 2025年前台沟通练习卷
- Co3O4八面体结构掺杂工程学设计及其酸性析氧反应性能研究
- 第7章 相交线与平行线(知识+5大易错+)(知识清单)(解析版)-人教版(2024)七下
- 2026年投资经营合同(1篇)
- 2026年木工包工包料合同(1篇)
- 私人二手车转让合同(4篇)
- 2025年8月31日宿州市萧县事业单位遴选面试真题及答案解析
- 2023浙江工业大学机械原理习题答案
- 中国铁塔股份有限公司代维单位星级评定方案2017年
- 江苏如东1100MW海上风电项目陆上换流站工程环评报告
- 《安全运动促健康》课件
- 日管控、周排查、月调度记录表
- 江苏省无锡市江阴市2023年事业单位考试A类《职业能力倾向测验》临考冲刺试题含解析
- GB/T 5752-2013输送带标志
- GB/T 3146.1-2010工业芳烃及相关物料馏程的测定第1部分:蒸馏法
- GB/T 31087-2014商品煤杂物控制技术要求
- GB/T 30812-2014燃煤电厂用玻璃纤维增强塑料烟道
- 住院医师规范化培训临床技能结业考核体格检查评分表(神经外科)
评论
0/150
提交评论