收藏 分享(赏)

数据结构与算法第3章栈和队列.pptx

上传人:Facebook 文档编号:9730976 上传时间:2019-08-29 格式:PPTX 页数:68 大小:376.13KB
下载 相关 举报
数据结构与算法第3章栈和队列.pptx_第1页
第1页 / 共68页
数据结构与算法第3章栈和队列.pptx_第2页
第2页 / 共68页
数据结构与算法第3章栈和队列.pptx_第3页
第3页 / 共68页
数据结构与算法第3章栈和队列.pptx_第4页
第4页 / 共68页
数据结构与算法第3章栈和队列.pptx_第5页
第5页 / 共68页
点击查看更多>>
资源描述

1、栈和队列是两种常用的数据类型,栈是限定仅在表尾进行插入和删除的线性表。,队列是限定仅在表尾进行插入、在表头进行删除的线性表。,第 3 章 限定性线性表栈和队列,1,2,3.1 栈,3.2 队列,3.3 总结与提高,本章作业与上机题目,第 3 章 限定性线性表栈和队列,3,3.1.1 栈的定义,3.1.2 栈的表示和实现,3.1.3 栈的应用举例,3.1.4 栈与递归的实现,返回,4,定义:,作为一种限定性线性表,是将线性表的 插入和删除运算限制为仅在表的一端进行。,通常将表中允许进行插入、删除操作的一端称为 栈顶 (Top),表的另一端被称为栈底 (Bottom)。,当栈中没有元素时称为空栈。

2、,栈的插入操作被形象地称为进栈或入栈。,栈的删除操作称为出栈或退栈。,特点:后进先出(LIFO),进栈,出栈,练习题,设有4个元素1、2、3、4依次进栈,而出栈操作可随时进行(进出栈可任意交错进行,但要保证进栈次序不破坏1234的相对次序),请写出所有不可能的出栈次序和所有可能的出栈次序。 如入栈序列为123456,则能否得到出栈序列435612和135426,5,6,抽象数据类型:,ADT Stack ADT Stack,数据对象:D ai | ai ElemSet, i=1,2,.,n, n0 ,数据关系:R1 | ai-1, aiD, i=2,.,n 约定an 端为栈顶,a1 端为栈底。

3、,基本操作:1. InitStack(S) 2. ClearStack(S)3. IsEmpty(S) 4. IsFull(S) 5. Push(S,x) 6. Pop(S,x) 7. GetTop(S,x),返回,7, 顺序栈, 链栈,8, 顺序栈,用顺序存储结构实现的栈,即利用一组地址 连续的存储单元依次存放自栈底到栈顶的数 据元素,同时由于栈的操作的特殊性,还必 须附设一个位置指针top(栈顶指针)来动态 地指示栈顶元素在顺序栈中的位置。,9,顺序栈,的C语言描述,#define Stack_Size 50typedef struct StackElementType elemStack

4、_Size; int top; /*用来存放栈顶元素下标*/ SeqStack;,A,B,C,top,top,top,top,D,top,E,top,top = -1表示空栈。,10,顺序栈的基本操作:, 初始化, 判栈空, 判栈满, 进 栈, 出 栈, 取栈顶元素,11,顺序栈的基本操作:, 初始化,void InitStack(SeqStack *S) S-top= -1; ,#define Stack_Size 50typedef struct StackElementType elemStack_Size; int top; SeqStack;,12,顺序栈的基本操作:,判栈空,int

5、 IsEmpty(SeqStack *S) return(S-top=-1?TRUE:FALSE); ,#define Stack_Size 50typedef struct StackElementType elemStack_Size; int top; SeqStack;,13,顺序栈的基本操作:,判栈满,int IsFull(SeqStack *S) return(S-top= Stack_Size-1?TRUE:FALSE); ,#define Stack_Size 50typedef struct StackElementType elemStack_Size; int top;

6、SeqStack;,14,顺序栈的基本操作:, 进栈,int Push(SeqStack * S, StackElementType x) if(S-top= Stack_Size-1) return(FALSE); S-top+;S-elemS-top=x;return(TRUE); ,#define Stack_Size 50typedef struct StackElementType elemStack_Size; int top; SeqStack;,15,顺序栈的基本操作:,出栈,int Pop(SeqStack * S, StackElementType *x) if(S-top

7、=-1) return(FALSE);else *x= S-elemS-top;S-top-; return(TRUE); ,#define Stack_Size 50typedef struct StackElementType elemStack_Size; int top; SeqStack;,16,顺序栈的基本操作:,取栈顶元素,int GetTop(SeqStack S, StackElementType *x) if(S-top=-1)return(FALSE);else*x = S-elemS-top;return(TRUE); ,#define Stack_Size 50typ

8、edef struct StackElementType elemStack_Size; int top; SeqStack;,17,两栈共享技术,双端栈,主要利用了栈“栈底位置不变,而栈顶位置动态变化” 的特性。首先为两个栈申请一个共享的一维数组空间 SM,将两个栈的栈底分别放在一维数组的两端,分 别是0,M-1。,top0,top1,18,两栈共享,数据结构定义:,#define M 100 typedef struct ElemType StackM;int top2;DqStack;,19,两栈共享,初始化,void InitStack(DqStack *S) S-top0=-1;S-

9、top1=M; ,#define M 100 typedef struct ElemType StackM;int top2;DqStack;,20,两栈共享, 进栈,int Push(DqStack *S, StackElementType x, int i) if(S-top0+1=S-top1) return(FALSE);switch(i) case 0:S-top0+; S-StackS-top0=x; break;case 1: S-top1-; S-StackS-top1=x; break;default: return(FALSE);return(TRUE); ,#define

10、 M 100 typedef struct ElemType StackM;int top2;DqStack;,21,两栈共享, 出栈,int Pop(DqStack *S, StackElementType *x, int i) switch(i) case 0: if(S-top0=-1) return(FALSE);*x=S-StackS-top0; S-top0- -;break;case 1: if(S-top1=M) return(FALSE);*x=S-StackS-top1;S-top1+;break;default: return(FALSE);return(TRUE);,#

11、define M 100 typedef struct ElemType StackM;int top2;DqStack;,22,链栈,采用链表作为存储结构实现的栈。为便于操作, 采用带头结点的单链表实现栈。因为栈的插入和 删除操作仅限制在表头位置进行,所以链表的表 头指针就作为栈顶指针。,若top-next=NULL,则代表空栈。,注意:链栈在使用完毕时,应该释放其空间。,23,链栈,数据结构定义:,typedef struct node StackElementType data;struct node *next; LinkStackNode, *LinkStack;,24,链栈, 进栈

12、,temp,a1,temp,a2,temp-next=top-next;, top-next=temp;,25,int Push(LinkStack top, StackElementType x) LinkStackNode * temp;temp=(LinkStackNode * )malloc(sizeof(LinkStackNode);if(temp=NULL) return(FALSE); temp-data=x; temp-next=top-next;top-next=temp; return(TRUE); ,typedef struct node StackElementType

13、 data;struct node *next; LinkStackNode, *LinkStack;,链栈, 进栈,26,链栈, 出栈,int Pop(LinkStack top, StackElementType *x) LinkStackNode * temp; temp=top-next;if(temp=NULL) return(FALSE);top-next=temp-next; *x=temp-data;free(temp); return(TRUE); ,typedef struct node StackElementType data;struct node *next; Li

14、nkStackNode, *LinkStack;,返回,则 检验括号是否匹配可用栈来实现。,假设在表达式中 ()或( ) 等为正确的格式, ( )或( )或 ()) 均为不正确的格式。,应用:, 括号匹配问题,27,28,1)凡出现左括弧,则进栈;,2)凡出现右括弧,首先检查栈是否空若栈空,则表明该“右括弧”多余,否则和栈顶元素比较,若相匹配,则“左括弧出栈” ,否则表明不匹配。,3)表达式检验结束时,若栈空,则表明表达式中匹配正确,否则表明“左括弧”有余。,算法的设计思想:, ( ) ,(,),(,29,第 3 章 栈和队列,3.1 栈,应用:, 括号匹配问题,算法实现,void Brack

15、etMatch(char *str) Stack S; int i; char ch;InitStack(,算法基于原理: N = (N div d)d + N mod d,计算顺序,输出顺序,例如:(1348)10 = (2504)8 , 其运算过程如下: N N div 8 N mod 8 1348 168 4 168 21 0 21 2 5 2 0 2,应用:,数制转换,30,数制转换算法 void Conversion(int N) /*对任意非负十进制数N,打印等值的八进制数*/ Stack S; int x; /*S为顺序栈或链栈*/InitStack( ,31,32,应用:,表达

16、式求值,问题分析:,Exp = a b + c d / e f,1)确定计算规则,即明确运算符的优先级;,2)确定当前处理字符是运算符还是操作数;,(限于二元运算符的表达式),3)每个运算符的运算次序要由它之后的一个运算符来定。,应用:,33,应用:,表达式求值,3) 若当前字符是操作数, 则直接压入操作数栈;,4) 若当前字符是操作符,且运算符的优先级高于栈顶运算符则进栈;,5) 否则,从操作数栈中弹出两个操作数并弹出操作符栈的栈顶运算符,经计算后将结果压入操作数栈。,(限于二元运算符的表达式),算法思路:,1) 设立操作数栈与操作符栈;,2) 设表达式的结束符为“#”,预设运算符栈的栈底为

17、“#”;,34,应用:,表达式求值,(限于二元运算符的表达式),例如:A/BC+D*E,#,A,/,B,C,BC,T(1)=,T(1),A/T(1),T(2)=,T(2),+,D,*,E,D*E,T(3)=,T(3),T(3)+T(2),T(4)=,T(4),操作数的栈底中存着最终的表达式结果。,35,应用:,表达式求值,(限于二元运算符的表达式),返回,当在一个函数的运行期间调用另一个函数时, 在运行该被调用函数之前, 需先完成三项任务:,将所有的实在参数、返回地址等信息传递给被调用函数保存;为被调用函数的局部变量分配存储区;将控制转移到被调用函数的入口。,36,从被调用函数返回调用函数之前

18、, 应该完成下列三项任务:,保存返回的计算结果(用函数名,引用参数) ;释放被调函数的数据区(局部量);依照被调函数中保存的返回地址将控制转移到调用函数。,37,多个函数嵌套调用的规则是:,此时的内存管理实行“栈式管理”,后调用先返回 !,例如: main( ) void a( ) void b( ) a( ); b( ); /main / a / b,main的数据区,函数a的数据区,函数b的数据区,每个函数数据区含:参数、局部变量、返回地址等信息,38,递归工作栈:递归函数执行过程中占用的数据区 工 作 记 录: 每一层的参数、局部变量、返回地址等构成的记录(数据区) 当前活动记录:栈顶工

19、作记录(当前函数数据区) 当前环境指针:递归工作栈的栈顶指针,指向当前活动记录。(指示当前函数数据区),可见:栈是函数过程嵌套调用及递归调用管理的有效手段,递归函数执行过程是直接或间接地调用自己, 可视为同一函数自己对自己进行嵌套调用。例如:,void a( ) void a( ) void b( ) a( ); b( ); a( ); /a 直接递归 / a / b 间接递归,例Hanoi塔问题:有3个塔座x, y, z, 在塔座x上插有n个大小不同的圆盘, 从小到大且自上而下编号为1,2,n; 按规则将它们一个个搬到塔座z上, y可用作辅助塔座。规则为: (1) 每次只能移动一个圆盘; (

20、2) 圆盘可放在任意塔座上; (3)任何时刻塔座上都不得将大盘压在小盘之上。,分析: n=1时:直接从塔座x移动到塔座z上; n1时:先将上面的n-1个圆盘移到塔座y上, 然后将n号盘移到塔座z上, 再将y上的n-1个圆盘移到塔座z上。这样就将问题的规模缩小1, 利用递归可实现。,40,void hanoi (int n; char x, char y,char z) /* 将塔座x上按直径由小到大且至上而下编号为1至n的n个圆盘按规则搬到塔座z上,y可用作辅助塔座。*/ 1 2 IF (n=1) 3 move(x, 1, z); /*将1号盘从x移到z*/9 ,4 ELSE 5 hanoi(

21、n-1, x, z, y); /*将x上n-1个盘移到y, z作辅助塔*/ 6 move(x, n, z); /*将n号圆盘从x移到z*/ 7 hanoi(n-1, y, x, z); /*将y上n-1个盘移到z, x作辅助塔*/ 8 ,41,void hanoi (int n; char x, char y,char z) 1 2 IF (n=1) 3 move(x, 1, z); 4 ELSE hanoi(n-1, x, z, y); move(x, n, z); hanoi(n-1, y, x, z); 8 调用程序:返回地址为0hanoi(3, A, B, C); 0 . . . .

22、. .,0 3 A B C,6 2 A C B,6 1 A B C,8 1 C A B,42,A B C,. hanoi(n,A,B,C);.,1 A-C,2 A-B,1 C-B,3 A-C,1 B-A,2 B-C,1 A-C,43,递归程序结构清晰、程序可读性强,且其正确性易于证明,给用户编程带来很大方便。,但递归程序效率很低(时、空两方面),使用时多加权衡。,当问题满足如下条件是,可设计地归算法: 1、原问题可以层层分解为类似的子问题,子问题规模比原问题小; 2、规模最小的子问题具有直接解。,设计递归算法的方法是: 1.寻找分解方法,将原问题分解为类似的子问题求解; 2.设计递归出口,按最

23、小规模子问题确定递归终止条件;,返回,44,45,3.2.1 队列的定义,3.2.2 队列的表示和实现,3.2.3 队列的应用举例,返回,46,定义:,限定所有的插入操作在表的一端进行,而删除操作在表的另一端进行的线性表。,通常将表中允许进行插入操作的一端称为队尾 (rear), 允许进行删除操作的一端称为队头(front)。,当队列中没有元素时称为空队。,队列的插入操作称为入队。,队列的删除操作称为出队。,特点:先进先出(FIFO),入队,出队,47,抽象数据类型:,ADT Queue ADT Queue,数据对象:D ai | ai ElemSet, i=1,2,.,n, n0 ,数据关系

24、:R1 | ai-1, aiD, i=2,.,n 约定an 端为队尾,a1 端为队头。,基本操作:1. InitQueue(&Q) 2. ClearQueue(&Q)3. IsEmpty(Q) 4. IsFull(Q) 5. EnterQueue(&Q,x) 6. DeleteQueue(&Q,x) 7. GetHead(Q,&x) 8.DestoryQueue(&Q),返回,48, 链队列,链式映象,顺序映象, 循环队列,q.front q.rear,q.front q.rear,空的链队列,LinkQueue q, 链队列,非空的链队列,49,50, 链队列,typedef struct

25、node QueueElementType data;struct node *next; LinkQueueNode;typedef struct LinkQueueNode *front;LinkQueueNode *rear; LinkQueue;LinkQueue *Q;,数据结构定义,51,链队列,int InitQueue(LinkQueue *Q) Q-front=(LinkQueueNode *)malloc(sizeof(LinkQueueNode);if(Q-front!=NULL)Q-rear=Q-front;Q-front-next=NULL;return(TRUE);

26、else return(FALSE);,初始化,52,链队列,int EnterQueue(LinkQueue *Q,QueueElementType x) LinkQueueNode * N;N =(LinkQueueNode *)malloc(sizeof(LinkQueueNode);if(N!=NULL) N-data=x;N-next=NULL;Q-rear-next=N;Q-rear=N;return(TRUE);else return(FALSE);,入队,53,链队列,int DeleteQueue(LinkQueue *Q,QueueElementType *x)LinkQu

27、eueNode * p;if(Q-front=Q-rear) return(FALSE); p=Q-front-next;Q-front-next=p-next;*x=p-data;free(p);return(TRUE);,出队,尽管链队列使用方便,但由于其指针多占存储空间,有时仍需要用顺序结构来表示队列。,顺序队列中也需要两个“指针”:头指针指示队头元素的当前位置;尾指针指示队尾元素的后一个位置。, 循环队列,54,存储结构定义,#define maxsize 50typedef struct QueueElementtype element maxsize;int front;int r

28、ear;seqQueue;, 循环队列,55,此时入队操作为: sq. elementsq.rear =x; sq.rear= sq.rear+1;,出队操作为: x=sq. elementsq.front;sq.front= sq.front+1;,头指针指示队头元素的当前位置;,尾指针指示队尾元素的后一个位置。,seqQueue sq;,56, 循环队列,假溢出现象描述,q.rear,q.front,A,B,C,D,E,F,G,H,当 sq.rearmaxsize 时, 队列满 (即上溢), 但此时头指针指示的元素之前可能还有空单元, 此现象称为假溢出;,解决假溢出的方法可以是:把顺序结构

29、设想为一个循环表, 这样就可以利用头指针前的空单元, 这就构成了循环队列。, 循环队列,假溢出现象:,57,58, 循环队列,59, 循环队列,循环队列需解决的两个问题:,一.下标计算问题,以前 入队操作为: sq. elementsq.rear =x; sq.rear= sq.rear+1;,出队操作为: x=sq. elementsq.front;sq.front= sq.front+1;,现在 入队操作为: sq. elementsq.rear =x; sq.rear= (sq.rear+1)% maxsize;,出队操作为: x=sq. elementsq.front;sq.front

30、= (sq.front+1)% maxsize ;,二、循环队列“空”与“满”的判定,cq.front=cq.rear 队“空”? 队“满”?,解决办法1: 设队“空” 、队“满” 标志; 解决办法2: 少用一个元素空间, 则:cq.front=(cq.rear+1)% maxsize 为满, 循环队列,60,循环队列需解决的两个问题:,61,循环队列:,初始化,void InitQueue(SeqQueue *Q)Q-front=Q-rear=0;,62,循环队列:,入队,int EnterQueue(SeqQueue *Q,QueueElementType x)if(Q-rear+1)%

31、maxsize =Q-front) return(FALSE);Q-elementQ-rear=x;Q-rear=(Q-rear+1)% maxsize;return(TRUE);,63,循环队列:,出队,int DeleteQueue(SeqQueue *Q,QueueElementType *x)if(Q-front= Q-rear) return(FALSE);*x=Q-elementQ-front;Q-front=(Q-front+1)% maxsize;return(TRUE);,返回,队列的应用举例:,打印杨辉三角问题:,第 1 行 1 第 2 行 1 1 第 3 行 1 2 1

32、第 4 行 1 3 3 1 第 5 行 1 4 6 4 1,杨辉三角(二项式系数值):,设第 i行的值:(a0=0) a1ai (ai+1=0) 则第i+1 行的值:bj = aj-1+aj, j=1,2,i+1,64,65,出队元素s=1; 队首元素e=0,s+e入队,0入队, 队中为第2行数据,出队元素s=0; 队首元素e=1,s+e入队,出队元素s=1; 队首元素e=1,s+e入队,出队元素s=1; 队首元素e=0,s+e入队,0入队, 队中为第3行数据,void yhsj(int h) SeqQueue q; QueueElementType e,s;InitQueue( ,返回,66,1. 掌握栈和队列类型的特点,并能在相应的应用问题中正确选用它们。,2. 熟练掌握栈类型的两种实现方法,特别应注意栈满和栈空的条件以及它们的描述方法。,3. 熟练掌握循环队列和链队列的基本操作实现算法,特别注意队满和队空的描述方法。,4. 理解递归算法执行过程中栈的状态变化过程。,本章学习要点,67,作业及上机题目 P102_104,栈:3、4 队列:7、8 综合:12 上机题目:实习题1(必须使用栈),68,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报