版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第三章栈和队列
第三章栈和队列
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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- DB37T 4791-2024煤矿井下超大断面硐室施工技术规范
- 江西省丰城市第九中学2025届高三(复读班)上学期第三次段考政治试卷(含答案)
- 读书社团活动策划(9篇)
- 歌颂教师主题演讲稿三分钟歌颂教师的主题集合4篇
- 光船租赁合同(2篇)
- 《职场沟通》电子教案 项目五 职场沟通中的礼仪准备
- 2025年紫外光固化油墨合作协议书
- 2025年付里叶红外分光光度计项目合作计划书
- 2025年低温超导材料项目发展计划
- 卖车场地租赁协议
- 甘肃省兰州市第一中学2023-2024学年高一上学期期末考试 物理 含解析
- 草地调查规划学知到智慧树章节测试课后答案2024年秋东北农业大学
- 酒店吃饭餐饮合同范例
- 2024年矿产资源开发咨询服务合同
- 上海市2024-2025学年高一语文下学期期末试题含解析
- 职业生涯规划成品
- 期末模拟卷01(全国适用)-【中职专用】高二语文上学期职业模块期末模拟卷(解析版)
- 建筑物拆除的拆除工厂考核试卷
- 广东省深圳市2023-2024学年高二上学期期末测试英语试卷(含答案)
- 人教版一年级数学2024版上册期末测评(提优卷一)(含答案)
- 医疗护理员理论知识考核试题题库及答案
评论
0/150
提交评论