收藏 分享(赏)

数据结构2_第3章.ppt

上传人:dzzj200808 文档编号:3336672 上传时间:2018-10-15 格式:PPT 页数:55 大小:344.50KB
下载 相关 举报
数据结构2_第3章.ppt_第1页
第1页 / 共55页
数据结构2_第3章.ppt_第2页
第2页 / 共55页
数据结构2_第3章.ppt_第3页
第3页 / 共55页
数据结构2_第3章.ppt_第4页
第4页 / 共55页
数据结构2_第3章.ppt_第5页
第5页 / 共55页
点击查看更多>>
资源描述

1、堆栈 堆栈的应用 队列 队列的应用,第三章 堆栈和队列,3.1 栈 ( Stack ),只允许在一端插入和删除的顺序表 允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom) 特点后进先出 (LIFO),退栈,进栈,栈的存储结构 顺序栈 实现:一维数组sM,栈顶指针top,指向实际栈顶 后的空位置,初值为0,进栈,A,出栈,栈满,B,C,D,E,F,设数组维数为M top=0,栈空,此时出栈,则下溢(underflow) top=M,栈满,此时入栈,则上溢(overflow),栈空,栈的基本操作,1、初始化 Initiate(s) 2、进栈 push( s,x) 3、退栈 po

2、p ( s) 4、取栈顶元素 gettop( s) 5、判栈是否非空 Notempty( s) 6、置空栈 SETNULL(s),栈的顺序存储结构,顺序栈的定义 typedef int elemtype; #define maxsize 64 typedef struct elemtype datamaxsize;int top; seqstack;,栈的基本运算 初始化 initiate(seqstack *s) s-top-1; 判栈空 int notEMPTY(seqstack *s) if (s-top=0) return 1;else return 0; ,进栈 seqstack *

3、PUSH(seqstack *s,datatype x) if (s-top=maxsize-1) printf(“overflown”);return NULL;else s-top+;s-datas-topx;return s; ,退栈 datatype POP(seqstack *s) if (s-toptop-;return(s-datas-top+1); ,取栈顶 datatype TOP(seqstack *s) if (s-topdatas-top); ,两个堆栈共享空间,基本操作: 1、初始化 2、进栈 3、出栈,栈的链接表示 链式栈,链式栈无栈满问题,空间可扩充 插入与删除仅

4、在栈顶处执行 链式栈的栈顶在链头 适合于多栈操作,栈的链接存储结构,链栈的结点定义 typedef int elemtype; typedef struct node elemtype data;struct node *next; slnodetype;,链栈的进栈算法 linkstack *PUSHLSTACK(slnodetype *top, elemtype x) slnodetype *p;pmalloc(sizeof(linkstack);p-datax; p-nexth-next; h-next=p;return h; ,链栈的出栈算法 linkstack *POPLSTACK(

5、slnodetype *top, datatype *datap) slnodetype *p;if (top-next=NULL) printf(“under flown”); return NULL;elseptop-next; *datapp-data;top-nextp-next;free(p);return top; ,例: 对于一个栈,给出输入项A、B、C,如果输入项序列 由ABC组成,试给出所有可能的输出序列。,A进 A出 B进 B出 C进 C出 ABC A进 A出 B进 C进 C出 B出 ACB A进 B进 B出 A出 C进 C出 BAC A进 B进 B出 C进 C出 A出 B

6、CA A进 B进 C进 C出 B出 A出 CBA不可能产生输出序列CAB,栈的应用举例文字编辑器 seqstack s; EDIT() char c;SETNULL( ,例 递归的执行情况分析,递归过程及其实现 递归:函数直接或间接的调用自身叫 实现:建立递归工作栈,void print(int w) int i;if ( w!=0) print(w-1);for(i=1;i=w;+i)printf(“%3d,”,w);printf(“/n”); ,Ch3_10.c,运行结果: 1, 2,2, 3,3,3,,递归调用执行情况如下:,表达式求值,中缀表达式 后缀表达式(RPN)a*b+c ab*

7、c+a+b*c abc*+a+(b*c+d)/e abc*d+e/+,中缀表达式:操作数栈和运算符栈,例 计算 2+4-3*6,(1) 对每种运算符赋予一个优先数,如: 运算符: * / + - 优先数: 2 2 1 1 语句结束符“;”的优先数为 0 (2) 可以使用两个工作栈:数栈(NS);运算符栈(OS)。 (3) 编译程序自左向右扫描至语句结束符,处理的原则是: 凡遇到操作数,一律进数栈; 当遇到运算符时,则将该运算符的优先数与运算符栈中的栈顶元素的优先数相比较。若该运算符的优先数大,则进栈;反之,则取出栈顶的运算符,并在数栈中连续取出两个栈顶元素作为运算对象进行运算,并将运算结果存入

8、数栈,然后继续比较该运算符与栈顶元素的优先数。,后缀表达式特点 1、与相应的中缀表达式中的操作数次序相同 2、没有括号,后缀表达式求值步骤: 1、读入表达式一个字符 2、若是操作数,压入栈,转4 3、若是运算符,从栈中弹出2个数,将运算结果再压入栈 4、若表达式输入完毕,栈顶即表达式值;若表达式未输入完,转1,例 计算 4+3*5,后缀表达式:435*+,后缀表达式的处理过程 A + ( B C / D) E,A,B,C,D,E,A,B,C,T1,A,B,T2,A,T3,中缀表达式转换为后缀表达式,当前运算符,栈顶运算符,中缀表达式转换为后缀表达式的处理规则,1、如为操作数,直接输出到队列;

9、2、如当前运算符高于栈顶运算符,入栈; 3、如当前运算符低于栈顶运算符,栈顶运算符退栈,并输出到队列,当前运算符再与栈顶运算符比较; 4、如当前运算符等于栈顶运算符,且栈顶运算符为“(”,当前运算符为“)”,则栈顶运算符退栈,继续读下一符号; 5、如当前运算符等于栈顶运算符,且栈顶运算符为“#”,当前运算符也为“#”,则栈顶运算符退栈,继续读下一符号;,队列 ( Queue ),定义 队列是只允许在一端删除,在另一端插入的顺序表 允许删除的一端叫做队头(front),允许插入的一端叫做队尾(rear)。 特性 先进先出(FIFO, First In First Out),队列的进队和出队,进队

10、时队尾指针先进一 rear = rear + 1,再将新元素按 rear 指示位置加入。出队时队头指针先进一 front = front + 1,再将下标为 front 的元素取出。队满时再进队将溢出出错;队空时再出队将队空处理。,顺序队列的指针说明 typedef struc datatype datamaxsize;int front,rear; sequeue;,队列的基本操作,1、置空队列 2、判定队列是否为空 3、取队列头元素 4、将新元素插入队尾 5、队列头元素出队,顺序队列置队空 SETNULL(sequeue *sq) sq-frontmaxsize-1;sq-rearmaxs

11、ize-1; ,顺序队列判队空 int EMPTY(sequeue *sq) if (sq-rear=sq-front) return(TRUE);elsereturn(FALSE); ,顺序队列取队头元素 datatype FRONT(sequeue *sq) if (EMPTY(sq) printf(“queue is emptyn”);return NULL;elsereturn (sq-front+1)%maxsize; ,顺序队列入队 int ENQUEUE(sequeue *sq,datatype x) if (sq-front=(sq-rear+1)%maxsize)printf

12、(“sequeue is fulln”;return NULL);else sq-rear(sq-rear+1)%maxsize;sq-datasq-rearx; return(TRUE); ,顺序队列出队 datetype DEQUEUE(sequeue *sq) if (EMPTY(sq)printf(“queue is emptyn”);return NULL;elsesq-front(sq-front+1)%maxsize;return(sq-datasq-front); ,顺序队列存在问题 设数组维数为M,则: 当front=-1,rear=M-1时,再有元素入队发生溢出真溢出 当f

13、ront-1,rear=M-1时,再有元素入队发生溢出假溢出 解决方案 队首固定,每次出队剩余元素向下移动浪费时间 循环队列 基本思想:把队列设想成环形,让sq0接在sqM-1之后,若rear+1=M,则令rear=0;,实现:利用“模”运算 入队: rear=(rear+1)%M; sqrear=x; 出队: front=(front+1)%M; x=sqfront; 队满、队空判定条件,存储队列的数组被当作首尾相接的表处理。 队头、队尾指针加1时从maxSize -1直接进到0,可用语言的取模(余数)运算实现。 队头指针进1: front = (front + 1) % maxSize;队

14、尾指针进1: rear = (rear + 1) % maxSize; 队列初始化:front = rear = 0; 队空条件:front = rear; 队满条件:(rear + 1) % maxSize = front,循环队列 (Circular Queue),队空:front=rear 队满:front=rear,解决方案: 1.另外设一个标志以区别队空、队满 2.少用一个元素空间:队空:front=rear队满:(rear+1)%M=front,循环队列的进队和出队,队列的链接表示 链式队列,队头在链头,队尾在链尾。 链式队列在进队时无队满问题,但有队空问题。 队空条件为 fron

15、t = NULL,链队列结点类型定义 typedef struct linklist *front,*rear; linkqueue;,链队列置队空 SETNULL(linkqueue *q) q-frontmalloc(sizeof(linklist);q-front-nextNULL;q-rearq-front; ,链队列判队空 int EMPTY(linkqueue *q) if q-front=q-rear) return(TRUE);else return(FALSE); ,链队列取队头结点 datatype FRONT(linkqueue *q) if (EMPTY(q)print

16、f(“queue is emptyn”);return NULL;elsereturn(q-front-next-data); ,链队列入队 ENQUEUE(linkqueue *q,datatype x) q-rear-nextmalloc(sizeof(linklist);q-rearq-rear-next;q-rear-datax;q-rear-nextNULL; ,链队列出队 datatype DEQUEUE(linkqueue *q) linklist *s;if (EMPTY(q)printf(“queue is emptyn”);return NULL;else sq-front

17、;q-frontq-front-next;free(s);return(q-front-data); ,1 2 3 4 5 6 7 8,1 2 3 4 5 6,队列的应用举例求迷宫的最短路径,需要解决的问题1:如何从某一坐标点出发搜索其四周的邻点,需要解决的问题2:如何存储搜索路径,需要解决的问题3:如何防止重复到达某坐标点,需要解决的问题4:如何输出搜索路径,#define r 64 #define m2 10 #define n2 10 int mm2-2,nn2-2;typedef struct int x,y;int pre; sqtype; sqtype sqr;,struct mo

18、ved int x,y; move8;int mazem2n2;,int SHORTPATH(int maze2) int i,j,v,front,rear,x,y;sq1.x1; sq1.y1; sq1.pre0;front1; rear1;maze11-1;while(front=rear) xsqfront.x; ysqfront.y;for (v=0;v8;v+) ix+movev.x;jy+movev.y;if (mazei,j=0) rear+sqrear.xi; sqrear.yj;sqrear.prefront;mazeij-1;,if (i=m) ,PRINTPATH(sqtype sq,int rear) int i;i=rear;do printf(“n(%d,%d)”,sqi.x,sqi.y);isqi.pre; while (i!=0); ,

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

当前位置:首页 > 高等教育 > 大学课件

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


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

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

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