C语言数据结构-第04讲 栈.ppt
《C语言数据结构-第04讲 栈.ppt》由会员分享,可在线阅读,更多相关《C语言数据结构-第04讲 栈.ppt(82页珍藏版)》请在三一办公上搜索。
1、实用数据结构基础,第3章 栈,第 3 章 栈,知 识 点 栈的定义和特点栈的基本运算和算法栈的典型应用难 点 后缀表达式的算法数制的换算利用本章的基本知识设计相关的应用问题,要 求 掌握栈的特点掌握栈的基本运算熟悉栈的各种实际应用 能设计栈的应用的典型算法了解栈的运算时间复杂度分析,第3章 目录,3-1 栈的定义与运算 3-2 栈的存储和实现 3-3 栈的应用举例小 结实验3 栈子系统习题3,3-1 栈的定义和运算,3-1-1 栈(Stack)的定义1.栈的定义 栈是限制在表尾进行插入和删除的线性表。,进栈,出栈,图3-1栈的 示意图,2.栈的特性(1)栈的主要特点是“后进先出”(2)允许插入
2、、删除的这一端称为栈顶(Top),另一端称为栈底(Bottom)。3.应用实例(1)分币筒;(2)铁路调度站。,3-1-2 栈的运算1进栈:Push(&s,x)初始条件:栈s已存在且非满。操作结果:在栈顶插入一个元素x,栈中多了一个元素。2出栈:Pop(&s)初始条件:栈s存在且非空。操作结果:删除栈顶元素,栈中少了一个元素。3读栈顶元素:ReadTop(s,&e)初始条件:栈s已存在且非空。操作结果:输出栈顶元素,但栈中元素不变。,4.判栈空:SEmpty(s)初始条件:栈s已存在。操作结果:若栈空则返回为0,否则返回为1。5.判栈满:SFull(s)初始条件:栈s已存在。操作结果:若栈满则
3、返回为0,否则返回为1。6.显示栈元素:ShowStack(s)初始条件:栈s已存在,且非空。操作结果:显示栈中所有元素。,3-2 栈的存储和实现,3-2-1 顺序栈1 顺序栈的实现(1)用一维数组实现顺序栈 设栈中的数据元素的类型是字符型,用一个足够长度的一维数组s来存放元素,数组的最大容量为MAXLEN,栈顶指针为top,则顺序栈可以用C(或C+)语言描述如下:#define MAXLEN 10/分配最大的栈空间 char sMAXLEN;/数据类型为字符型 int top;/定义栈顶指针,(2)用结构体数组实现顺序栈 顺序栈的结构体描述:#define MAXLEN 10/分配最大的栈空
4、间 typedef struct/定义结构体 datatype dataMAXLEN;/datatype可根据用需要定义类型 int top;/定义栈顶指针 SeqStack;再定义一个指向顺序栈的指针:SeqStack*S;/定义S为结构体类型的指针变量,(3)栈操作的示意图如图3-3所示。,top=-1,top=0,top=5,top=3,top=9,(a)(b)(c)(d)(e),当top=-1时,表示栈空,如图3-3(a);当top=0时,表示栈中有一个元素,如图3-3(b)表示栈中已输入一个元素A;入栈时,栈顶指针上移,指针top加1,如图3-3(c)是6个元素入栈后的状况;出栈时,
5、栈顶指针下移,指针top减1,如图3-3(d)是在F、E相继出栈后的情况。此时栈中还有A、B、C、D 4个元素,top=3,指针已经指向了新的栈顶。但是出栈的元素F、E仍然在原先的存储单元,只是不在栈中了,因为栈是只能在栈顶进行操作的线性表。当top=9时,即top=MAXLEN1,表示栈满,如图3-3(e)。,2顺序栈运算的基本算法(1)置空栈 首先建立栈空间,然后初始化栈顶指针。SeqStack*Snull()SeqStack*s;s=new(SeqStack);/在C语言中用s=malloc(sizeof(SeqStack);s-top=1;/置栈空 return s;,(2)进栈 进栈
6、运算是在栈顶位置插入一个新元素x,其算法步骤为:(a)判栈是否为满,若栈满,作溢出处理,并返回0;(b)若栈未满,栈顶指针top加1;(c)将新元素x送入栈顶,并返回1。int Push(SeqStack*s,datatype x)if(s-top=MAXLEN1)return 0;/栈满不能入栈,且返回 0 else s-top+;s-datas-top=x;/栈不满,则压入元素x return 1;/进栈成功,返回1,(3)出栈 出栈运算是指取出栈顶元素,赋给某一个指定变量x,其算法步骤为:(a)判栈是否为空,若栈空,作下溢处理,并返回0;(b)若栈非空,将栈顶元素赋给变量x;(c)指针t
7、op减1,并返回1。int Pop(SeqStack*s,datatype*x)if(SEmpty(s)return 0;/若栈空不能出栈,且返回0 else*x=s-datas-top;/栈不空则栈顶元素存入*x s-top-;return 1;/出栈成功,返回1,(4)读栈顶元素datatype ReadTop(SeqStack*s)if(SEmpty(s)return 0;/若栈空,则返回0 else return(s-datas-top);/否则,读栈顶元素,但指针未移动(5)判栈空int SEmpty(SeqStack*s)if(s-top=1)return 1;/若栈空,则返回1
8、else return 0;/否则返回0,(6)判栈满 int SFull(SeqStack*s)if(s-top=MAXLEN1)return 1;/若栈满,则返回1 else return 0;/否则返回0 3-2-2 链栈1链栈的实现 用链式存储结构实现的栈称为链栈。因为链栈的结点结构与单链表的结构相同,通常就用单链表来实现,在此用LinkStack表示,即有:typedef struct stacknode/栈的存储结构 datatype data;/定义数据类型 struct stacknode*next;/定义一个结构体的链指针 stacknode;,*Linkstack;Link
9、stack top;/top为栈顶指针,由于栈中的操作只能在栈顶进行的,所以用链表的头部做栈顶是最合适的。链栈结构如图3-4所示。,图3-4 链栈示意图,2链栈基本操作:(1)入栈 void Push(linkstack*s,int x)stacknode*p=new stacknode;/申请一个新结点p-data=x;/数据入栈p-next=s-top;/修改栈顶指针s-top=p;,(2)出栈 int Pop(linkstack*s)int x;/定义一个变量x,用以存放出栈的元素 stacknode*p=s-top;/栈顶指针指向p x=p-data;/栈顶元素送x s-top=p-n
10、ext;/修改栈顶指针 delete p;/回收结点p return x;/返回栈顶元素,(3)显示 void ShowStack(linkstack*s)stacknode*p=s-top;if(p=NULL)/若栈空,作“栈空”显示 printf(栈为空);else printf(栈元素为:);while(p!=NULL)/栈非空,则显示栈中所有元素 printf(%6d,p-data);/输出一个元素 p=p-next;/修改栈顶指针 printf(n);,3-3.栈的应用举例,3-3-1 数制转换 数值进位制的换算是计算机实现计算和处理的基本问题。比如将十进制数N转换为j进制的数,其解
11、决的方法很多,其中一个常用的算法是除j取余法。将十进制数每次除以j,所得的余数依次入栈,然后按“后进先出”的次序出栈便得到转换的结果。其算法原理是:N=(N/j)*j+N%j 其中:/为整除,%为求余,【例3-1】将十进制数138转换为二进制数 N N/2(整除)N%2(求余)138 69 0 69 34 1 34 17 进 0 出 17 8 栈 1 栈 8 4 次 0 次 4 2 序 0 序 2 1 0 1 0 1(138)10=(10001010)2,1算法思想如下:(1)若 N0,则将N%j 取得的余数压入栈s中,执行(2);若N=0,将栈s的内容依次出栈,算法结束。(2)用N/j 代替
12、 N(3)当N0,则重复步骤(1)、(2)。,2.算法的实现:void Conversion(int n)/将十进制数n转换为二进制数 linkstack s;int x;s.top=NULL;do x=n%2;/除2取余 n=n/2;stacknode*p=new stacknode;/申请一个新结点 p-next=s.top;/修改栈顶指针 s.top=p;s.top-data=x;/入栈,while(n);printf(转换后的二进制数值为:);while(s.top)/余数出栈处理 printf(%d,s.top-data);/输出栈顶的余数 stacknode*p=s.top;/修改
13、栈顶指针 s.top=s.top-next;delete p;/回收一个结点,C语言中用free p,3-3-2 表达式求值表达式是由运算对象、运算符、括号等组成的有意义的式子。1中缀表达式(Infix Notation)一般我们所用表达式是将运算符号放在两运算对象的中间,比如:a+b,c/d等等,我们把这样的式子称为中缀表达式。2后缀表达式(Postfix Notation)后缀表达式规定把运算符放在两个运算对象(操作数)的后面。在后缀表达式中,不存在运算符的优先级问题,也不存在任何括号,计算的顺序完全按照运算符出现的先后次次序进行。3中缀表达式转换为后缀表达式 其转换方法采用运算符优先算法
14、。转换过程需要两个栈:一个运算符号栈和一个后缀表达式输出符号栈。,(1)读入操作数,直接送输出符号栈。(2)读入运算符,压入运算符号栈。(a)若后进的运算符优先级高于先进的,则继续进栈;(b)若后进的运算符优先级不高于先进的,则将运算符号栈内高于或等于后进运算符级别的运算符依次弹出后,自己进栈。(3)括号处理:(a)遇到开括号“(”,进运算符号栈;(b)遇到闭括号“)”,则把最靠近的开括号“(”,以及其后进栈的运算符依次弹出到输出符号栈(括号均不压入输出符号栈)。(4)遇到结束符“#”,则把运算符号栈内的所有运算符号依次弹出,并压入输出符号栈。(5)若输入为+、单目运算符,改为0与运算对象在前
15、,运算符在后。例如:A,转换为:0A。,【例3-2】A/B C+D*EA*C,【例3-3】3+4/(25(6+15)*8,得到后缀表达式为:3 4 25 6 15+/8*+4后缀表达式求值 后缀表达式求值的运算要用到一个数栈stack和一个存放后缀表达式的字符型数组exp。其实现过程就是从头至尾扫描数组中的后缀表达式:(1)当遇到运算对象时,就把它插入到数栈stack中;(2)当遇到运算符时,就执行两次出栈的操作,对出栈的数进行该运算符指定的运算,并把计算的结果压入到数栈stack。把它插入到数栈stack中;(3)重复(1)、(2),直至扫描到表达式的终止符“#”,在数栈的栈顶得到表达式的值
16、。,以例【例3-3】的结果看后缀表达式的计算过程:3 4 25 6 15+-/8*+第1次计算结果为:21 第2次计算结果为:4 第3次计算结果为:1 第4次计算结果为:8 第5次计算结果为:11,3-3-3 子程序调用(Subroutine Call)在计算机程序设计中,子程序的调用及返回地址就是利用堆栈来完成的。在C(或C+)语言的主函数对无参子函数的嵌套调用过程中,在调用子程序前,先将返回地址保存到堆栈中,然后才转去执行子程序。当子函数执行到return语句(或函数结束)时,便从栈中弹出返回地址,从该地址处继续执行程序。例如:主函数调用子函数a()时,则在调用之前先将a函数返回地址压入栈
17、中;在子函数a()中调用子函数b()时,又将b函数返回地址压人栈中;同样,在子函数b()中调用子函数c()时,又将c函数返回地址压人栈中。其调用返回地址进栈示意图如图3-5所示。,图3-5 无参函数嵌套调用返回地址进栈示意图 当执行完子函数c()以后,就从栈顶弹出c()函数返回地址,回到子函数b();子函数b()执行完毕返回时,又从栈顶弹出b函数返回地址,回到子函数a();子函数a()返回时,再在栈顶弹出a函数返回地址,回到主函数,继续执行主函数程序。无参函数嵌调用返回示意图如图3-6所示。,返回地址栈:,图3-6 无参函数嵌套调用返回示意图,3-3-4 递归调用1递归 一个直接调用自己,或者
18、通过一系列调用语句间接地调用自己的函数称为递归函数。在程序设计中,有许多实际问题是递归定义的,使用递归的方法编写程序将使许多复杂的问题大大简化。所以,递归是程序设计中的一个强有力的工具。2典型例子(1)2阶斐波那契(Fibonacci)数列,0 n=01 n=1Fib(n1)+Fib(n2)其它情况,Fib(n)=,(2)阶乘函数 n!的定义为:,Fac(n)=,1 n=0/递归终止条件,n*Fac(n-1)n0/递归步骤,根据定义不难写出相应的递归函数:int fac(int n)if(n=0)return 1;else return(n*fac(n1);,3-3-5 中断处理和现场保护1.
19、中断处理(Interrupt Processing)在C+语言中,系统调用是通过中断来进行,中断调用示意图如图3-8所示。,图3-8 中断调用示意图如 如果把中断处理想象成函数调用,则中断处理程序可以看成被调用的函数。,2.现场保护和恢复 执行中断时,微处理机有时必须对状态寄存器,累加器,以及相关的寄存器对进行现场保护(压栈);中断处理完毕,则必须按后进先出的原则恢复现场(出栈)。下面,我们以汇编语言来说明现场保护和恢复的原理:;接受中断处理 PUSH AX;保护现场 PUSH BX PUSH CX PUSH BP PUSHF;F状态寄存器进栈;中断处理 POPF;恢复现场,后进栈的先出栈 P
20、OP BP POP CX POP BX POP AX,(1)栈是一种运算受限制的线性表,它只允许在栈顶进行插入和删除等操作。(2)栈的逻辑结构和线性表相同,数据元素之间存在一对一的关系,其主要特点是“后进先出”。(3)栈的存储结构有顺序栈和链栈之分,要求掌握栈的C语言描述方法。(4)重点掌握在顺序栈和链栈上实现:进栈、出栈、读栈顶元素、判栈空和判栈满等基本操作。(5)熟悉栈在计算机的软件设计中的各种应用,能灵活应用栈的基本原理解决一些综合性的应用问题。,小 结,实验3 栈子系统,1实验目的(1)掌握栈的特点及其描述方法。(2)用链式存储结构实现一个栈。(3)掌握建栈的各种等基本操作。(4)掌握
21、栈的几个典型应用的算法。2.实验内容(1)设计一个字符型的链栈;(2)编写进栈、出栈、显示栈中全部元素的程序;(3)编写一个把十进制整数转换成二进制数的应用程序;(4)编写一个把中缀表达式转换成后缀表达式(逆波兰式)的应用程序;(5)设计一个选择式菜单,以菜单方式选择上述操作。,栈 子 系 统*1-进 栈*2-出 栈*3-显 示*4-数制转换*5-逆波兰式*0-返 回*请选择菜单号:*教材p64第3行void Stack(),在作为子系统上机时上机时改为:void main(),习题3,参考习题解答,返回,实用数据结构基础,第4章 队列,第4章 队列,知 识 点 队列的定义和特点队列的存储实现
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C语言数据结构-第04讲 语言 数据结构 04
链接地址:https://www.31ppt.com/p-6503898.html