版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第三章栈和队列
第三章栈和队列
3.1栈
3.2栈的应用举例
3.3栈与递归
3.4队列
3.5队列的应用3.1栈3.1.1栈的概念
3.1.2栈的顺序存储和实现
3.1.3栈的链式存储和实现
3.1.1栈的概念栈是限定仅能在表尾一端进行插入、删除操作的线性表;(a1,a2,...ai,…,an-1,an
)插入删除ana2a1栈的特点后进先出又称为后进先出表(LIFO表Last_inFirst_out)出栈进栈栈顶栈底ana2a13.1.1栈的概念栈的应用火车调度123基本操作初始化操作InitStack(&S)
功能:构造一个空栈S。销毁栈操作DestroyStack(&S)
功能:销毁一个已存在的栈。置空栈操作ClearStack(&S)
功能:将栈S置为空栈。判空操作StackEmpty(S)
功能:若栈S为空,则返回True,否则,栈不空返回False。ana2a1栈顶栈底
取栈顶元素操作GetTop(S,&e)
功能:取栈顶元素,并用e返回。
进栈操作Push(&S,e)
功能:元素e进栈。
退栈操作Pop(&S,&e)
功能:栈顶元素退栈,并用e返回。ana2a1栈顶栈底3.1.2栈的顺序存储和实现出栈进栈栈顶栈底ana2a1
顺序栈的类型定义#defineSTACK_INIT_SIZE100#defineSTACKINCREMENT10typedefstruct{
ElemType*base;//动态数组基址
intstacksize;//栈空间大小
}SqStack;SqStackS;ElemType*top//栈顶指针出栈进栈栈顶栈底ana2a1S.stacksizeS.topS.base
an
an-1a2a110099 n-110topbaseaabcdab空栈
a进栈
b,c,d进栈d,c出栈topbasetopbasetopbase
顺序栈的基本操作算法
约定:栈顶指针示栈顶元素的下一个位置
初始化操作InitStack(&S)功能:建空栈S.stacksizeS.topS.base100
99 n-110StatusInitList_Sq(SqStack&S){//建立空顺序栈S
S.base=(ElemType*)malloc(STACK_INIT_SIZE*sizeof(ElemType));
//为顺序栈动态分配存储空间
if(!S.base)exit(OVERFLOW);//分配失败
S.top=S.base;//栈顶指针初始化
S.stacksize=STACK_INIT_SIZE;returnOK;}//InitList_Sq
算法时间复杂度:O(1)S.stacksizeS.topS.base
an
an-1a2a110099 n-1100
销毁栈操作DestroyStack(&S)
功能:销毁一个已存在的栈NULLNULLStatusDestroyStack(SqStack&S){//销毁一个已存在的栈
free(S.base);
//释放栈空间
S.base=S.top=NULL;
S.stacksize=0;
returnOK;}//DestroyStack
置空操作ClearStack(&S)功能:将已存在的栈S,置成空栈99 n-110S.stacksizeS.topS.base
an
an-1a2a110099 n-110S.stacksizeS.topS.base
an
an-1a2a1100置空StatusDestroyStack(SqStack&S){//销毁一个已存在的栈
S.top=NULL;
//释放栈空间
returnOK;}//DestroyStack
进栈操作
Push(&S,e)
e进栈前e进栈后功能:将元素e压入栈顶S
an
an-1a2a1100
99 n-110S
ean
an-1a2a1100
99 n-110*S.top=e;S.top++;StatusPush(SqStack&S,ElemTypee){
//将元素e插入栈顶
*S.top=e;S.top++;
//元素e插入栈顶,修改栈顶指针
returnOK;
}//Pushif(S.top-S.base==S.stacksize)//栈满
{newbase=(ElemType*)realloc(S.base,
(S.stacksize+STACKINCREMENT)*sizeof(ElemType));
if(!newbase)exit(OVERFLOW);S.base=newbase;S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;}//if
出栈操作
Pop(&S,&e)功能:栈顶元素退栈,并用e返回。出栈操作前出栈操作后eanS
an
an-1a2a110099 n-110S
an
an-1a2a110099 n-110--S.top;e=*S.top;StatusPop(SqStack&S,ElemType&e){//删除栈顶元素,并用e返回其值
if(S.top==S.base)returnERROR;//栈空
--S.top;e=*S.top;
//读取栈顶元素,修改栈顶指针
returnOK;
}//PopS
an
an-1a2a110099 n-1103.1.3栈的链式存储和实现Sanan-1a1栈底栈顶typedefstructLNode{
ElemTypedata;
StructSNode*next;
}SNode,*SLinkList;SLinkListS;
//S栈顶指针3.1.3栈的链式存储和实现出栈e栈顶Sanan-1a1栈底e入栈栈顶Sanan-1a1栈底顺序栈和链式栈的比较栈的特点:后进先出时间效率所有操作都时间复杂度都是O(1)顺序栈和链式栈在时间效率上难分伯仲空间效率顺序栈须说明一个固定的长度链式栈的长度可变,但增加结构性开销
3.2栈的应用举例迷宫求解——搜索(深度优先)行编辑程序表达式括号匹配的检验表达式求值实现递归其它退栈进栈栈顶栈底ana2a1
数制转换十进制数到八进制数的转换算法基于下面整数性质
N=(Ndivd)×d+
Nmodd43=5×8+3
例(1348)10=(2504)8
,其运算过程如下:=2×83+5×82+0×8+4
=(2504)8
=(21×8+0)×8+4
=(2×8+5)×8+0)×8+4
=168×8+41348=(1348div8)×8+1348mod8
voidconversion(){//输入一个非负十进制数,输出八进制数
InitStack(S);//建空栈
scanf(“%d”,N);//输入一个非负十进制整数
while(N){//N不等于零循环
Push(S,N%8);//余数进栈
N=N/8;//整除运算,N=商
}
while(!StackEmpty){//输出栈中的八制数位
Pop(S,e);Printf(“%d”,e);
}
DestroyStack(S);//释放栈空间
}//conversion
迷宫问题输入数据:迷宫结果数据:从入口到出口的一条路径入口出口1234入口出口1234迷宫问题迷宫问题求解迷宫问题的基本步骤若当前位置“可通”,则纳入路径,继续探索;若当前位置“不可通”,换个方向继续探索;若四周“均已探索”,则后退一步,换个方向继续探索;入口出口1234括号匹配问题在表达式中,正确的格式([]())[([][])]在表达式中,不正确的格式:[(])())(()main(){…x=2;y=3;
z=x*x+y*y;}表达式求值-算符优先算法表达式的构成
表达式::=操作数+运算符+界符5+6(1+2)–4212355+6(1+2)–42表达式的求值
(数学上)4=5+63-42=5+18-42=23-42=23-8=151)确定表达式中算符运算顺序
2)按照算符的运算顺序进行计算算符优先关系表(1、2是相邻算符,1
左,2右)
1、2的优先关系有:1<2
1=2
1>22
1
+-*/()#>><<<>>>
><<<>>>>>><>>>>>><>><<<<<=>>>>>><<<<<=+-*/()##5+6(1+2)-42#表达式求值基本思路+(
从左向右扫描表达式:#5+6(1+2)-42
•
遇操作数——保存
•
遇运算符j
——与左运算符i比较
–若i<j
则保存
–若i>j
则i可进行运算;
–若i=j
需要消去括号;5612+<<<#<>后保存运算符优先级高OPTR栈#OPND栈5+6×(1+25
读入表达式:+6×(1+2)-4#1+2=36×3=185+18=2323-8=15表达式求值示意图(算符优先算法)1823-15×24×2=84×832
算符优先算法OperandTypeEvaluateExpression(){//算术表达式求值的算符优先算法。设OPTR和OPND分别为运算符栈和操作数栈,OP为运算符集合。
InitStack(OPTR);Push(OPTR,#);InitStack(OPND);c=getchar();//读入算术表达式
while(c!=‘#’||GetTop(OPTR)!=‘#’){if(!In(c,OP))//若为操作数进栈OPND{Push(OPND,c);c=getchar()}else{//若为运算符
switch(Precede(GetTop(OPTR),c)){case<://运算符进栈并接收下一字符
Push(OPTR,c);c=getchar();break;case=://脱括号并接收下一字符
Pop(OPTR,x);c=getchar();break;case>:Pop(OPTR,theta);Pop(OPND,b);Pop(OPND,a);Push(OPND,Operate(a,theta,b));break;}//switch}//if}//whilereturnGetTop(OPND);}//EvaluateExpression
中缀表达式5+6(1+2)–425612++42
-1234
后缀表达式
前缀表达式-+56+12421234
表达式的三种表达方式55例求解n!的递归函数
intfact(intn){if(n==1)return1;elsereturn(n*fact(n-1));}3.3栈与递归A(){…A();…}递归函数递归函数的执行过程中栈的作用函数的调用数据传递控制转移main(){intn=3;f(n);}intf(intn){r=1;for(i=1;i<=n;i++)
r=r*i;return(r);}调用返回递归函数的执行过程中栈的作用主调函数时涉及的数据函数实参返回地址被调函数涉及的数据函数形参局部变量函数返回值函数数据区参数返回地址等局部变量递归函数的执行过程中栈的作用(被调)函数数据区的分配对于非递归函数,数据区的分配可以在程序运行前进行,直到整个程序运行结束才释放,这种分配称为静态分配。内存代码区域全程/静态区域动态区域intf(intn){r=1;for(i=1;i<=n;i++)
r=r*i;return(r);}main(){intn=3;f(n);}main(){intn=3;fact(n);}intfact(intn){if(n==1)return(1);
elsereturn(n*fact(n-1));}调用n=3返回intfact(intn){if(n==1)return(1);
elsereturn(n*fact(n-1));}调用n=2返回参数返回地址等局部变量递归函数的执行过程中栈的作用函数数据区的分配对于递归函数,必须每调用一次就分配一块新的数据区,以存放当前函数所使用的数据,当函数结束返回时随即释放。即所谓的动态分配。代码区域全程/静态区域动态区域内存
函数返回顺序main()fac
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026浙江台州市黄岩经开投资集团有限公司下属公司招聘市场化工作人员8人备考题库含答案详解(满分必刷)
- 无人机行业应用(航测)电子教案 1.7 无人机测绘应用场景
- 2026中交天和机械设备制造有限公司常熟制造中心招聘4人备考题库含答案详解(黄金题型)
- 2026潍坊市蓝航技工学校教师招聘备考题库含答案详解(黄金题型)
- 2026浙江传媒学院招聘2人备考题库(2026年第二批)及答案详解(典优)
- 2026“才聚齐鲁 成就未来”山东土地城乡融合发展集团有限公司社会招聘2人备考题库及答案详解(各地真题)
- 2026北京房山区窦店第二小学招聘备考题库(含答案详解)
- 2026年青岛市房地产职业中等专业学校教师公开招聘备考题库(7人)及答案详解(有一套)
- 2026四川宜宾沿江建设投资集团有限公司下属股权企业招聘工作人员2人备考题库含答案详解(考试直接用)
- 2026河南郑州市社会福利院公益性岗位招聘4人备考题库有答案详解
- 2026洛阳钼业招聘笔试题及答案
- GB/T 30333-2025物流服务合同准则
- 安全生产月活动启动仪式
- 钢筋焊接缺陷及预防措施总结
- 黄金导购培训知识内容课件
- GB/T 18711-2025选煤用磁铁矿粉试验方法
- 海河的课件教学课件
- 项目招标技术文件合规性审查
- 种植绿萝的劳动课课件
- 移印基础知识培训课件
- 2025年媒体行业招聘面试指南与预测问题解答
评论
0/150
提交评论