收藏 分享(赏)

数据结构第三章..ppt

上传人:hwpkd79526 文档编号:7634374 上传时间:2019-05-22 格式:PPT 页数:59 大小:1.22MB
下载 相关 举报
数据结构第三章..ppt_第1页
第1页 / 共59页
数据结构第三章..ppt_第2页
第2页 / 共59页
数据结构第三章..ppt_第3页
第3页 / 共59页
数据结构第三章..ppt_第4页
第4页 / 共59页
数据结构第三章..ppt_第5页
第5页 / 共59页
点击查看更多>>
资源描述

1、3.1 栈 3.2 栈的应用举例 * 3.3 栈与递归实现 3.4 队列,【学习目标】,1. 掌握栈和队列这两种抽象数据类型的特点,并能在相应的应用问题中正确选用它们。2. 熟练掌握栈类型的两种实现方法。3. 熟练掌握循环队列和链队列的基本操作实现算法。,【重点和难点】 掌握栈和队列这两种结构的特点,以便能在应用问题中正确使用。,【知识点】顺序栈、链栈、循环队列、链队列,引例,衣物箱子:放衣服的时候,顺序放入,1件,2件,n件。取衣服的时候次序应是什么样的? 2. 在日常生活中,为了维持正常的社会秩序而出现的常见现象是什么?,必然是依从上往下的次序,即n,2,1。它们遵循的是“后进先出“的规律

2、,这正是本章要讨论的“栈“的结构特点。,栈和队列是两种特殊的线性表,是操作受限的线性表,称限定性数据结构。,是“排队“。在计算机程序中,模拟排队的数据结构是“队列“。,3.1 栈(stack),1. 栈的定义和特点 定义:只允许在一端插入和删除的线性表允许插入和删除的一端称为栈顶 (top),另一端称为栈底(bottom) 特点: 后进先出 (LIFO),2. 栈抽象数据类型的定义,ADT Stack 数据对象:D ai | ai ElemSet, i=1,2,.,n, n0 数据关系:R1 | ai-1, aiD, i=2,.,n 约定an 端为栈顶,a1 端为栈底。 基本操作: InitS

3、tack(&S) 操作结果:构造一个空栈S。 DestroyStack(&S) 初始条件:栈S已存在。 操作结果:栈S被销毁。 ClearStack(&S) 初始条件:栈S已存在。 操作结果:将S清为空栈。StackEmpty(S) 初始条件:栈S已存在。 操作结果:若栈S为空栈,则返回true,否则false,StackLength(S) 初始条件:栈S已存在。操作结果:返回S的元素个数,即栈的长度。 GetTop(S, &e) 初始条件:栈S已存在且非空。操作结果:用e返回S的栈顶元素。 Push(&S, e) 初始条件:栈S已存在。 操作结果:插入元素e为新的栈顶元素。 Pop(&S,

4、&e) 初始条件:栈S已存在且非空。操作结果:删除S的栈顶元素,并用e返回其值。 ADT Stack,3. 栈的存储结构,利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top指示栈顶元素在顺序栈中的位置;base表示栈底指针.,(1)栈的数组表示 顺序栈,顺序栈的实现:一维数组sM,栈顶指针top,指向实际栈顶 后的空位置,初值为0,进栈,A,出栈,栈满,B,C,D,E,F,设数组维数为M top=0,栈空,此时出栈,则下溢(underflow) top=M,栈满,此时入栈,则上溢(overflow),栈空,顺序栈的存储,与书上不同,书上繁琐 #define MAXSI

5、ZE 100 typedef int ElemType; typedef structElemType aMAXSIZE;int top; SqStack; SqStack s;,s.top=0 空栈,A,B,s.top=2 进栈2个元素,A,B,s.top=5 MAXSIZE-1 满栈,C,D,E,输出栈,void Create_Sqs(SqStack ,创建栈,void Output_Sqs(SqStack ,出栈,void push(SqStack ,进栈,ElemType pop(SqStack ,(2)栈的链接表示 链式栈,链式栈无栈满问题,空间可扩充 插入与删除仅在栈顶处执行 链式

6、栈的栈顶在链头 结点定义typedef struct LStack ElemType data;struct LStack *next; LStack;,top,data,next,栈底,栈顶,4. 栈的主要算法(带头结点),初始化 void init(LStack * ,相关定义 #include typedef int ElemType; typedef struct LStack ElemType data;struct LStack *next; LStack;,初始化 LStack *init() LStack *top;top=new LStack;top-next=NULL;re

7、turn top; ,LStack *head; head=init();,LStack *head; init(head);,创建 void create(LStack *top) int n,i;LStack *p;coutn;for (i=1; ip-data;p-next=top-next;top-next=p; ,输出(从栈顶开始) void output(LStack *top) LStack *p;p=top-next;if (p=NULL) coutdatanext;coutendl; ,进栈 void push(LStack *top, ElemType e) LStack

8、*p;p=new LStack;p-data=e;p-next=top-next;top-next=p; ,.,栈底,top,头结点,a1,.,栈底,top,出栈 ElemType pop(LStack *top) int x;LStack *p;if (top-next=NULL) coutnext;x=p-data;top-next=p-next;delete(p);return x; ,在一个程序中同时使用两个栈,栈顶指针是栈顶元素的地址或是栈顶前一元素的地址,确定标准是什么?,由程序员自己确定,在压栈和弹栈操作时来实现,3.2 栈的应用举例,1. 过程的嵌套调用,1.读入字符串 2.去

9、掉空格(原串) 3.压入栈 4.原串字符与出栈字符依次比较若不等,非回文若直到栈空都相等,回文,字符串:“madam im adam”,2. 回文游戏:顺读与逆读字符串一样(不含空格),3. 多进制输出,已知十进制数N,转为d进制(d=2,8,16) 方法:N除以d取余,直至商为0,余数倒排 设使用顺序栈结构void conversion(SqStack ,4. 表达式求值,1)运算符的优先级关系表 1先读到的运算符, 2后读到的运算符 2)算法:设运算符栈OPTR,操作数栈OPND 当 (c# | OPTR顶#) 数:进栈OPND,读c;运算符:与OPTR栈顶元素比a) c的优先级高:入OP

10、TR,读c ;b) c的优先级低:OPTR出一个,OPND出两个,运算结果入OPND ,不读c ;c) 相等: OPTR出一个脱括号,读c ; ,例 #3*(7-2)#,初始状态,c=3,c=* #*,c=( *(,c=7,c=- (-,c=2,c=) -),c=) (=),c=# *#,* 3.3 栈与递归实现,例 递归的执行情况分析,void print(int w) int i;if ( w!=0) print(w-1);for(i=1;i=w;+i)printf(“%3d,”,w);printf(“/n”); ,运行结果: 1, 2,2, 3,3,3,,递归:函数直接或间接的调用自身

11、实现:建立递归工作栈,递归调用执行情况如下:,利用栈和递归解决的几个经典问题,【Hanoi塔问题】 【迷宫问题】 【八皇后问题】 【背包问题】,【 汉诺塔问题】,有A,B,C三个塔座,A上套有n个直径不同的圆盘,按直径从小到大叠放,形如宝塔,编号1,2,3n。要求将n个圆盘从A移到C,叠放顺序不变,移动过程中遵循下列原则: 每次只能移一个圆盘 圆盘可在三个塔座上任意移动 任何时刻,每个塔座上不能将大盘压到小盘,解决方法:,n=1时,直接把圆盘从A移到C n1时,先把上面n-1个圆盘从A移到B,然后将n号盘从A移到C,再将n-1个盘从B移到C。即把求解n个圆盘的Hanoi问题转化为求解n-1个圆

12、盘的Hanoi问题,依次类推,直至转化成只有一个圆盘的Hanoi问题,【迷宫问题】,求迷宫入口(1,1)到出口(i,i)的所有路径,【八皇后问题】,设在初始状态下在国际象棋棋盘上没有任何棋子(皇后)。然后顺序在第1行,第2行,第8行上布放棋子。在每一行中有8个可选择位置,但在任一时刻,棋盘的合法布局都必须满足3个限制条件,即任何两个棋子不得放在棋盘上的同一行、或者同一列、或者同一斜线上。试编写一个递归算法,求解并输出此问题的所有合法布局。,【背包问题】,设有一个背包可以放入的物品的重量为s,现有n件物品,重量分别为w1, w2, , wn。问能否从这n件物品中选择若干件放入此背包中,使得放入的

13、重量之和正好为s。如果存在一种符合上述要求的选择,则称此背包问题有解(或称其解为真);否则称此背包问题无解(或称其解为假)。,3.4 队列 ( Queue ),定义 队列是只允许在一端删除,在另一端插入的顺序表 允许删除的一端叫做队头(front),允许插入的一端叫做队尾(rear)。 特性 先进先出(FIFO, First In First Out),a0 a1 a2 an-1,front,rear,队列的进队和出队原则,进队时先将新元素按 rear 指示位置加入,队尾指针再进一 rear = rear + 1。出队时先将下标为 front 的元素取出,队头指针先进一 front = fro

14、nt + 1。队满时再进队将溢出出错;队空时再出队将队空处理。解决队空而不能插入的办法之一:将队列元素存放数组首尾相接,形成循环(环形)队列。,队列的进队和出队示例,front,rear,空队列,front,rear,A进队,A,front,rear,B进队,A B,front,rear,C, D进队,A B C D,front,rear,A退队,B C D,front,rear,B退队,C D,front,rear,E,F,G进队,C D E F G,C D E F G,front,rear,H进队,溢出,1. 队列的抽象数据类型的定义 ADT Queue 数据对象:Dai | aiElem

15、Set, i=1,2,.,n, n0 数据关系:R1 | ai-1, ai D, i=2,.,n 约定其中a1 端为队列头,an 端为队列尾。 基本操作: InitQueue(&Q) 操作结果:构造一个空队列Q。,DestroyQueue(&Q) 初始条件:队列Q已存在。 操作结果:队列Q被销毁,不再存在。ClearQueue(&Q) 初始条件:队列Q已存在。 操作结果:将Q清为空队列。 QueueEmpty(Q) 初始条件:队列Q已存在。 操作结果:若Q为空队列,则返回TRUE,否则返回FALSE。 QueueLength(Q) 初始条件:队列Q已存在。 操作结果:返回Q的元素个数,即队列的

16、长度。,GetHead(Q, &e) 初始条件:Q为非空队列。 操作结果:用e返回Q的队头元素。 EnQueue(&Q, e) 初始条件:队列Q已存在。 操作结果:插入元素e为Q的新的队尾元素。 DeQueue(&Q, &e) 初始条件:Q为非空队列。操作结果:删除Q的队头元素,并用e返回其值。 ADT Queue,2. 队列的顺序存储结构 实现:用一维数组实现sqM,rear=0 front=0,队空,1,2,3,4,5,0,front,J1,J1,J3入队,J1,J2,J3,rear,J4,J5,J6入队,J4,J5,J6,front,设两个指针front,rear,约定: rear指示队

17、尾元素的下一个位置; front指示队头元素,空队列条件:front= =rear 入队列:sqrear+=x; 出队列:x=sqfront+;,J1,J2,J3出队,J1,J2,J3,front,存在问题设数组维数为M,则: 当front=0,rear=M时,再有元素入队发生溢出真溢出 当front0,rear=M时,再有元素入队发生溢出假溢出 解决方案 队首固定,每次出队剩余元素向下移动浪费时间 循环队列 基本思想:把队列设想成环形,让sq0接在sqM-1之后,若rear=M,则令rear=0;,循环队列 (Circular Queue),实现:利用“模”运算 入队: sqrear=x;

18、rear=(rear+1)%M; 出队: x=sqfront; front=(front+1)%M; 队满判定条件: (rear+1)%M=front、 front=rear 队空判定条件:front=rear,队列的顺序存储结构表示循环队列,#define MAXQSIZE 100 Typedef structElemType elemMAXSIZE; int front; /头指针,若队列不空,指向队头元素;int rear; /尾指针,若队列不空,指向队尾元素i的下一个位置char full; SqQueue; 循环队列解决假溢出: 当下标从0,1,2到MAXSIZE-1时,再取零值。,

19、如何判断队列“空”和“满”状态(Q.front=Q.rear?) 1)另设一个标志位,以区别队列是“空”还是“满”; 初始化,void SetNull(SqQueue ,若full为F ,则Q.elemQ.rear=e;Q.rear=(Q.rear+1) % MAXSIZE;若Q.front=Q.rear,置full为T ;,void EnQueue(SqQueue ,入队操作,若full为T或rear!=front,则x=Q.elemQ.front;Q.front=(Q.front+1) % MAXSIZE;只要出队就置full为F,ElemType DeQueue(SqQueue ,出队操

20、作,如何输出?思考,输出操作,2)少用一个元素空间,约定以“队列头指针在队列尾指针的下一位置(指环状的下一位置)上”作为队列呈“满”状态的标志。书本P64,3. 队列的链式表示 链队列,队头在链头,队尾在链尾。 链式队列在进队时无队满问题,但有队空问题。 队空条件为 front -next= NULL,data,next,队尾,队头,Q.front,Q.rear,队列的链式存储结构,Typedef struct QNodeElemType data;struct QNode *next; QNode,*QueuePtr; Typedef structQNode *front;QNode *re

21、ar; LinkQueue;,几种链式队列的状态,Q,4,具有两个元素的链队列,7 NULL,NULL,Q,空队列,NULL NULL,Q,销毁后的队列,Front,Front,Rear,Rear,LinkQueue,QNode,Q.front,Q.rear,空队列,Q.front,Q.rear,Q.front,Q.rear,Q.front,Q.rear,X ,Y ,X,Y ,X,元素X入队列,元素Y入队列,元素X出队列,置空队,void initqueue(LinkQueue *Q) p=new QNode;p-next=NULL;Q-front=p;Q-next=p; ,在链式队列尾插入新

22、元素算法,void EnQueue(LinkQueue *Q, ElemType e) p=new QNode;p-data=e;p-next=NULL:Q-rear-next=p;Q-rear=p; ,在链式队列头删除旧元素算法,ElemType DeQueue(LinkQueue *Q) if (Q-front=Q-rear) coutfront-next;x=p-data;Q-front-next=p-next;if (p=Q-rear) Q-rear=Q-front; /*当队列中只有一个元素时,防止丢失尾指针*/delete(p);return(x); ,本章小结,栈 栈的应用 队列,习题讲解,1.进站序列123,能得到的出站序列有? 2.进站序列为123456,能否得到435612,135426?,进入,驶出,

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

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

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


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

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

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