收藏 分享(赏)

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

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

1、2019年8月29日,数据结构讲义,1,第3章 栈和队列, 理解栈的定义、特征及基本运算; 掌握栈的两种存储结构及基本运算的实现; 理解队列的定义、特征及基本运算; 掌握队列的两种存储结构及基本运算的实现。,2019年8月29日,数据结构讲义,2,引例,餐馆中一叠一叠的盘子:如果它们是按 1,2,n 的次序往上叠的,那么使用时候的次序应是什么样的? 2. 在日常生活中,为了维持正常的社会秩序而出现的常见现象是什么?,必然是依从上往下的次序,即n,2,1。它们遵循的是“后进先出“的规律,这正是本章要讨论的“栈“的结构特点。,栈和队列是两种特殊的线性表,是操作受限的线性表,称限定性数据结构。,是“

2、排队“。在计算机程序中,模拟排队的数据结构是“队列“。,2019年8月29日,数据结构讲义,3,3.1 栈,3.1.1 栈的定义及基本运算3.1.2 栈的存储及运算实现,2019年8月29日,数据结构讲义,4,3.1.1 栈的定义及基本运算,1.栈的定义栈是限制在表的一端进行插入和删除的线性表。允许插入、删除的这一端称为栈顶,另一个固定端称为栈底。当表中没有元素时称为空栈。,右图所示栈中有三个元素,进栈的顺序是a1、a2、a3,当需要出栈时其顺序为a3、a2、a1,所以栈又称为后进先出的线性表(Last In First Out),简称 LIFO表。,2019年8月29日,数据结构讲义,5,2

3、.栈的基本运算: 栈初始化:Init_Stack(s)操作结果是构造了一个空栈。 判栈空:Empty_Stack(s)操作结果是若s为空栈返回为1,否则返回为0。 入栈: Push_Stack(s,x)操作结果是在栈s的顶部插入一个新元素x,x成为新的栈顶元素。 出栈:Pop_Stack(s)在栈s存在且非空的情况下,操作结果是将栈s的顶部元素从栈中删除。 读栈顶元素:Top_Stack(s)在栈s存在且非空情况下,操作结果是读栈顶元素,栈不变化。,2019年8月29日,数据结构讲义,6,练习,一个栈的入栈序列是a,b,c,d,e,则栈的不可能的输出序列是()。 A. edcba B. dec

4、ba C. dceab D. abcde,2019年8月29日,数据结构讲义,7,3.1.2 栈的存储及运算实现 顺序栈,和顺序表相似,顺序栈的类型描述如下:#define MAXSIZE 1024 typedef structdatatype dataMAXSIZE;int top;SeqStack;定义一个指向顺序栈的指针: SeqStack *s;,通常0下标端设为栈底,栈顶指针top值为-1,表示空栈,2019年8月29日,数据结构讲义,8,(a):空栈; (c):A、B、C、D、E 5个元素依次入栈之后; (d):在图(c)之后E、D相继出栈,top指针已经指向了新的栈顶,则元素D、

5、E已不属于栈中元素。,2019年8月29日,数据结构讲义,9, 置空栈 首先建立栈空间,然后初始化栈顶指针。,【算法3-1】置空栈算法 SeqStack *Init_SeqStack() SeqStack *s;s=(SeqStack *) malloc(sizeof(SeqStack); /*申请栈空间*/if (!s) printf(”空间不足”n);return NULL; /*未申请到足够大的存储空间,返回空指针*/else s-top=-1; /*初始化栈顶指针*/return s; /*申请到栈空间,返回栈空间地址*/,2019年8月29日,数据结构讲义,10,判空栈,【算法3-2

6、】判栈空算法 int Empty_SeqStack(SeqStack *s) if (s-top=-1)return 1; /*空栈返回1*/,elsereturn 0; ,2019年8月29日,数据结构讲义,11,入栈,【算法3-3】入栈算法int Push_SeqStack(SeqStack *s, datatype x) if (s-top=MAXSIZE-1)return 0; /*栈满不能入栈,返回错误代码0*/else s-top+; /*栈顶指针向上移动*/s-datas-top=x; /*将x至入新的栈顶*/return 1; /*入栈成功,返回成功代码1 */,2019年8月

7、29日,数据结构讲义,12,入栈,【算法3-3】入栈算法int Push_SeqStack(SeqStack *s, datatype x) if (s-top=MAXSIZE-1)return 0; /*栈满不能入栈,返回错误代码0*/else s-top+; /*栈顶指针向上移动*/s-datas-top=x; /*将x至入新的栈顶*/return 1; /*入栈成功,返回成功代码1 */,2019年8月29日,数据结构讲义,13,出栈,【算法3-4】出栈算法int Pop_SeqStack(SeqStack *s, datatype *x) /*通过*x返回原栈顶元素*/if (Empt

8、y_SeqStack(s)return 0; /*栈空不能出栈,返回错误代码0*/else *x=s-datas-top; /*保存栈顶元素值*/s-top-; /*栈顶指针向下移动*/return 1; /*返回成功代码1 */,2019年8月29日,数据结构讲义,14,出栈,【算法3-4】出栈算法int Pop_SeqStack(SeqStack *s, datatype *x) /*通过*x返回原栈顶元素*/if (Empty_SeqStack(s)return 0; /*栈空不能出栈,返回错误代码0*/else *x=s-datas-top; /*保存栈顶元素值*/s-top-; /*

9、栈顶指针向下移动*/return 1; /*返回成功代码1 */,2019年8月29日,数据结构讲义,15,取栈顶元素,【算法3-5】取栈顶元素算法int Top_SeqStack(SeqStack *s, datatype *x) /*仅是读取栈顶元素,栈顶指针不发生变化*/*栈顶元素可以通过参数返回*/if ( Empty_SeqStack (s) ) return 0; /*栈空无元素*/else *x=sdatastop;return 1;,2019年8月29日,数据结构讲义,16,几点注意:(1) 对于顺序栈,入栈时,首先判栈是否满了,栈满时,不能入栈; 否则出现空间溢出,引起错误,

10、这种现象称为上溢。栈满的条件为:s-top= =MAXSIZE-1(2) 出栈和读栈顶元素操作,先判栈是否为空,为空时不能操作,否则产生错误。(3) 通常栈空时常作为一种控制转移的条件。(4) 入栈和出栈操作的时间复杂度?,2019年8月29日,数据结构讲义,17,通常链栈用单链表表示,其结点结构 与单链表的结构相同:typedef struct node datatype data;struct node *next;StackNode,* LinkStack;定义top为栈顶指针: LinkStack top ;因为栈中的主要运算是在栈顶插入、删除,显然在链表的头部做栈顶是最方便的。一般没

11、有必要象单链表那样为了运算方便附加一个头结点。, 链栈,2019年8月29日,数据结构讲义,18,链栈基本操作的实现如下: 置空栈 仅是需要将栈顶指针置为空即可。 判栈空 【算法3-6】判栈空算法 int Empty_LinkStack(LinkStack top) if (top=NULL) return 1; else return 0; ,2019年8月29日,数据结构讲义,19, 入栈 【算法3-7】入栈算法 LinkStack Push_LinkStack(LinkStack top, datatype x) StackNode *p;p=(StackNode *)malloc(si

12、zeof(StackNode);pdata=x; pnext=top;top=p;return top; ,2019年8月29日,数据结构讲义,20, 出栈 【算法3-8】出栈算法 LinkStack Pop_LinkStack (LinkStack top, datatype *x) StackNode *p;if (top=NULL) return NULL;else *x= topdata;p=top; top=topnext;free (p);return top; 思考:顺序栈和链栈哪个效率更高?为什么?,2019年8月29日,数据结构讲义,21,3.2 栈的应用举例,由于栈的“后进

13、先出”特点,在很多实际问题中都利用栈做一个辅助的数据结构来进行求解,下面通过几个例子进行说明。,2019年8月29日,数据结构讲义,22,例 3-1 简单应用:数制转换问题将十进制数N转换为r进制的数,其转换方法利用辗转相除法:以N=3467,r=8为例转换方法如下:N N / 8 (整除) N % 8(求余)3467 433 3 低433 54 154 6 66 0 6 高 所以:(3467)10 =(6613)8将得到的余数依次放入栈中。算法思想如下:当N0时重复(1),(2)(1) 若 N0,则将N % r 压入栈s中 ,执行(2); 若N=0,将栈s的内容依次出栈,算法结束。(2) 用

14、N / r 代替 N。,2019年8月29日,数据结构讲义,23,【算法3-9】数制转换算法1 typedef int DataType; void conversion(int N,int r) SeqStack *s; /*定义一个顺序栈*/datetype x;s = Init_SeqStack();while (N) Push_SeqStack(s,N%r); /*余数入栈 */N=N/r; /*商作为被除数继续 */while (!Empty_SeqStack(s) /*余数按顺序出栈*/ Pop_SeqStack(s, ,2019年8月29日,数据结构讲义,24,【算法3-10】数

15、制转换算法2 void conversion(int N,int r) int sL,top; /*定义一个顺序栈*/int x;top=-1; /*初始化栈*/while (N) s+top=N%r; /*余数入栈*/N=N/r; /*商作为被除数继*/while (top!=-1) /*余数按顺序出栈 */ x=stop-;printf (“%d“,x );printf (“n“ );,2019年8月29日,数据结构讲义,25,算法3-9 是将对栈的操作抽象为模块调用,使问题的层次更加清楚。算法3-10中直接用int数组s和int 变量top作为一个栈来使用。当应用程序中需要使用与数据保存

16、顺序相反的数据时,就要想到栈。通常用顺序栈较多。,2019年8月29日,数据结构讲义,26,求解思想:从入口出发,按某一方向向前探索,若能走通(未走过的),即某处可以到达,则到达新点,否则试探下一方向 ; 若所有的方向均没有通路,则沿原路返回前一点,换下一个方向再继续试探,直到所有可能的通路都探索到,或找到一条通路,或无路可走又返回到入口点。 回溯法:一种不断试探且及时纠正错误的搜索方法。,例 3-2 利用栈实现迷宫的求解 问题:心理学家把一只老鼠从入口处赶进迷宫。迷宫中设置很多隔壁,对前进方向形成了多处障碍,心理学家在迷宫的唯一出口处放置了一块奶酪,吸引老鼠在迷宫中寻找通路以到达出口。,20

17、19年8月29日,数据结构讲义,27,表示迷宫的数据结构设迷宫为m行n列,利用mazem+2n+2来表示一个迷宫。 mazeij=0 或 1,其中:0表示通路,1表示不通。 迷宫的定义如下: #define m 6 /* 迷宫的实际行 */ #define n 8 /* 迷宫的实际列 */ int maze m+2n+2 ;,如图表示的是一个68的迷宫。入口坐标为(1,1),出口坐标为(6,8)。,2019年8月29日,数据结构讲义,28,试探方向在上述表示迷宫的情况下,每个点有8个方向去试探。为了简化问题,方便地求出新点的坐标,将从正东开始沿顺时针进行的这8个方向的坐标增量放在一个结构数组m

18、ove8中。Move数组定义如下:typedef struct int x,y item ; item move8 ;,2019年8月29日,数据结构讲义,29,压入栈的是一个由行、列、方向组成的三元组,方向是指从该点沿哪个方向到达了下一点。,栈的设计 栈中元素的设计如下:typedef structint x , y , d ; / 行列坐标及方向datatype ; 栈的定义仍然为: SeqStack *s ;,2019年8月29日,数据结构讲义,30,对于上示迷宫,压入栈中的分别为:(1,1)1(2,2)1(3,3)0(3,4)0 (3,5)0(3,6)0(下脚标表示方向),2019年8

19、月29日,数据结构讲义,31,如何防止重复到达某点,以避免发生死循环一种方法是另外设置一个标志数组markmn,它的所有元素都初始化为0,一旦到达了某一点 (i,j)之后,使markij 置1,下次再试探这个位置时就不能再走了。另一种方法是当到达某点(i,j)后使mazeij 置 -1,以便区别未到达过的点,同样也能起到防止走重复点的目的,本书采用后者方法,算法结束前可恢复原迷宫。,2019年8月29日,数据结构讲义,32,迷宫求解算法思想如下:1栈初始化;2将入口点坐标及到达该点的方向(设为-)入栈3while (栈不空) 栈顶元素(x , y , d) 出栈 ; 求出下一个要试探的方向d+

20、 ;while (还有剩余试探方向时) if (d方向可走)则 (x , y , d)入栈 ;求新点坐标 (i, j ) ;将新点(i , j)切换为当前点(x , y) ;if ( (x ,)= =(,n) ) 结束 ;else 重置 d=0 ;else d+ ;,33,栈初始化; 将入口点坐标及到达该点的方向入栈; while (栈不空) 栈顶元素出栈 (x , y , d)求出下一个要试探的方向d+ ;while(还有剩余试探方向时) if (d方向可走) (x , y , d)入栈 ;求新点坐标 (i, j ) ;将新点(i , j)切换为当前点(x , y);if (x ,y)= =

21、(,n)结束 ;else 重置 d=0 ; else d+ ; ,int path(int mazemn; item move8) s=Init_SeqStack(); temp.x=1; temp.y=1; temp.d=-1; Push_SeqStack (s,temp); while (! Empty_SeqStack (s) ) Pop_SeqStack (s,temp);x=temp.x; y=temp.y; d=temp.d+1; while (d8) i=x+moved.x; j=y+moved.y; if (mazeij=0 ) temp=x, y, d; Push_SeqStack (s, temp ); x=i; y=j; mazexy=-1; if (x=m ,

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

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

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


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

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

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