PowerPoint Presentation

Similar documents
Microsoft PowerPoint - ch3.pptx

正文.doc

ebook39-5

Microsoft PowerPoint - 4.pptx

C 1

CC213

数据结构 Data Structure

ebook39-6

40 第二部分试题部分 9. 假设栈初始为空, 将中缀表达式 a/b+(c*d-e*f)/g 转换为等价的后缀表达式的过程中, 当扫描 到 f 时, 栈中的元素依次是 ( ) 2014 年全国试题 2(2) 分 A. +(*- B. +(-* C. /+(*-* D. /+-* 10. 循环队列存放

《C语言程序设计》教材习题参考答案

FY.DOC

1

OOP with Java 通知 Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢 学习使用文本编辑器 学习使用 cmd: Power shell 阅读参考资料

4

chap07.key

使 用 一 般 佇 列 存 放 資 料 時, 當 前 端 (Front) 尚 有 空 位 時, 再 加 入 元 素, 卻 發 現 此 佇 列 已 滿, 請 問 此 時 使 用 下 列 那 一 個 方 法 較 佳? (A) 優 先 佇 列 (B) 環 形 佇 列 (C) 雙 向 佇 列

概述

int *p int a 0x00C7 0x00C7 0x00C int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++;

全国计算机技术与软件专业技术资格(水平)考试

PowerPoint Presentation

Microsoft PowerPoint - Lecture3.ppt

新・明解C言語入門編『索引』

(Microsoft PowerPoint - \270\352\256\306\265\262\272c\302\262\263\370.ppt)

untitled

Microsoft Word - 数据结构实训与习题725xdy.doc

Generated by Unregistered Batch DOC TO PDF Converter , please register! 浙江大学 C 程序设计及实验 试题卷 学年春季学期考试时间 : 2003 年 6 月 20 日上午 8:3

Summary

C 1 # include <stdio.h> 2 int main ( void ) { 4 int cases, i; 5 long long a, b; 6 scanf ("%d", & cases ); 7 for (i = 0;i < cases ;i ++) 8 { 9

Microsoft PowerPoint - 8. 运算符重载 Operator Overloading.pptx

Microsoft Word - F7801B_ch04習題解答.doc

untitled

ebook14-4

Microsoft PowerPoint - 4. 数组和字符串Arrays and Strings.ppt [兼容模式]

大侠素材铺

第1章

6 C51 ANSI C Turbo C C51 Turbo C C51 C51 C51 C51 C51 C51 C51 C51 C C C51 C51 ANSI C MCS-51 C51 ANSI C C C51 bit Byte bit sbit

3. 給 定 一 整 數 陣 列 a[0] a[1] a[99] 且 a[k]=3k+1, 以 value=100 呼 叫 以 下 兩 函 式, 假 設 函 式 f1 及 f2 之 while 迴 圈 主 體 分 別 執 行 n1 與 n2 次 (i.e, 計 算 if 敘 述 執 行 次 數, 不

<4D F736F F D20C8EDC9E82DCFC2CEE7CCE22D3039C9CF>

Open topic Bellman-Ford算法与负环

(CIP) /. :, ISBN T P CIP (2005) : : 127 : : : : : 787 mm mm 1

2014年度厦门市工程系列高级专业技术职务任职资格

附件2:

untitled

Microsoft Word - 澎湖田調報告_璉謙組.doc

( CIP) /. :, ( ) ISBN TP CIP ( 2005) : : : : * : : 174 ( A ) : : ( 023) : ( 023)

c_cpp

PowerPoint Presentation

OOP with Java 通知 : Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢

2015年全国射箭冠军赛.xls

OOP with Java 通知 Project 2 提交时间 : 3 月 21 日晚 9 点 作业提交格式 学习使用 文本编辑器 cmd, PowerShell (Windows), terminal(linux, Mac)

,,,,,,,,,, ( http: \ \ www. ncre. cn,, ) 30,,,,,,,, C : C : : 19 : : : /16 : : 96 : : : ISBN 7

untitled

汇集全球21位医生的经验和智慧,总结出最实用的专业建议,这些都是最值得你牢记的健康提醒

1 行 业 发 展 不 平 衡 我 国 房 地 产 中 介 服 务 业 起 步 较 晚, 专 业 分 工 程 度 和 国 外 发 达 国 家 相 比 还 有 很 大 差 距 房 地 产 中 介 服 务 行 业 的 发 展 水 平 与 房 地 产 开 发 行 业 的 市 场 化 水 平 密 切 相 关

Microsoft Word - 01.DOC

_汪_文前新ok[3.1].doc

nooog

untitled

四川省普通高等学校

Ps22Pdf

Microsoft PowerPoint - string_kruse [兼容模式]

untitled

2013 C 1 #include <stdio.h> 2 int main(void) 3 { 4 int cases, i; 5 long long a, b; 6 scanf("%d", &cases); 7 for (i = 0; i < cases; i++) 8 { 9 scanf("%

山东建筑大学学分制管理规定(试行)

Microsoft PowerPoint - C语言课件-9-结构体.pptx

PowerPoint 演示文稿

什么是函数式编程?

《C语言程序设计》教材习题参考答案

3.1 num = 3 ch = 'C' 2

Transcription:

第 章 栈与队列 本章主题 : 栈和队列的应用 教学目的 : 掌握栈和队列的应用方法, 理解栈的重要作用 教学重点 : 利用栈实现行编辑, 利用栈实现表达式求值 教学难点 : 利用栈实现表达式求值 2011-10-18 1

.1 ADT 栈 ( 定义和运算 ) 1.. 栈的定义 栈 stack 是一种特殊的 ( 有序表 ) 线性表, 插入 或删除栈元素的运算只能在表的一端进行, 称运算 的一端为栈顶, 另一端称为栈底 - 特点 : 后进先出 栈又称为 后进先出 的线性表, 简称 LIFO 表 例 -1[ 系统栈 ] 处理程序运行时的函数调用 D C B A -1 top top top top top 原栈地址 返回地址 局部变量 原栈地址 返回地址 fp 函数 a1 fp 主函数 2011-10-18 2

结构 -11 ADT 栈 Structure Stack object: 零个或多个有穷有序表 Funtion: Stack CreateS(max_size); Boolean IsFull(Stack); Boolean IsEmpty(Stack); Stack Add(stack,item); element Delete(stack); End stack #define MaxSize 100 typedef struct { int key; element; element stack[maxsize MaxSize]; int top=-1; Boolean IsEmpty(Stack)::=top<0 Boolean IsFull(Stack)::=top>= )::=top>=maxsize 2011-10-18

顺序栈的几种状态 ( 最大长度 MaxSize 为 4) top D 2 2 C 2 top C 2 2 1 1 B 1 B 1 1 0 top A 0 A 0 A 0 0 top -1 top -1 (a) (b) (c) (d) (e) (a) 当栈中没有数据元素时, 表示为栈空 栈顶元素所对应的下标值 top=-1 (b) 表示在 (a) 基础上执行 Push(S, A ) 后得到这种状态 (c) 又有三个元素 B C D 先后入栈, 此时栈顶元素的下标值 top= 栈已满 (d) 表示在 (c) 状态下, 执行一次 Pop(S,x) 运算得到 (e) 表示在 (d) 状态下, 执行三次 Pop(S,x) 运算得到 此时栈顶下标值 top=-l 又变成栈空状态 2011-10-18 4

程序 -1 栈的基本操作 : 判空 满 插入 删除 element stack_empty(int *top) { if(*top== -1)return 1; element stack_full(int *top) { if(*top= =maxsize-1) return 1; void add(int *top, element item) { if(*top>=maxsize-1) 1){ stack_full(); return; stack[++*top ++*top]=item; element delete(int *top) { if(*top=-1) return stack_empty(); return stack[(*top) (*top)--]; 2011-10-18 5

* 顺序栈的 C 语言描述如下 : #define MaxSize 数组元素的最大个数 typedef struct { ElemType data[maxsize]; int top; STACK; ElemType 为栈中元素的数据类型 data 域 : 为一个一维数组, 用于存储栈中元素 top 域 : 栈顶指针 取值范围为 0~MaxSize-1 top=-1 表示栈空,top=MaxSize, top=maxsize-1 表示栈满 2011-10-18 6

* 栈的基本运算 [ 必须掌握 ] 初始化栈 InitStack(S) 设置一个空栈 S 压栈 Push(S,x) 将元素 x 插入栈 S 中, 使 x 成为栈 S 的栈顶元素 出栈 Pop(S,x) 当栈 S 不空时, 由 x 返回栈顶元素, 并从栈中删除栈顶元素 取栈顶元素 GetTop(S,x) 若栈 S 不空, 则由 x 返回栈顶元素 判栈空 Empty(S) 若栈 S 为空栈, 结果为 1,, 否则结果为 0 2011-10-18 7

.1.2 栈的顺序存储结构及其基本运算的实现 栈有两种存储表示方法 : 顺序存储和链式存储 1. 栈的顺序存储结构 栈的顺序存储结构简称为顺序栈顺序栈 通常由一个一维数组和 一个记录栈顶元素位置的变量组成 2. 基本运算在顺序存储结构的实现 初始化栈 InitStack(S) void InitStack(STACK *S) {s=(stack *)malloc(sizeof(stack)); S->top=-1; 2011-10-18 8

压栈 Push(S,x) 教材 :add(s,item) int Push(STACK *S,ElemType x) {if(s->top==maxsize-1){ printf("\n Stack is full!"); return 0; S->data[++S->top]=x; return 1; 出栈 Pop(S,x) 教材 :delete (s) int Pop(STACK *S) { int x; if(empty(s)){printf("stack error"); return 0; x=s->data[s->top--]; return x; stack *s; s=(stack *)malloc(sizeof(stack malloc(sizeof(stack)); s->top= >top=-1; 2011-10-18 9

取栈顶元素 GetTop(S,x) int GetTop(STACK *S, ElemType *x) { if(empty(s)){ printf("\n Stack is free!"); retrn 0; *x=s->data[s->top]; return *x; 判栈空 Empty(S) int Empty(STACK *S) { return (S->top==-1?1:0); 判栈满 full(s) int Empty(STACK *S) { return (S->top= =maxsize-1?1:0); 2011-10-18 10

例题 : 栈的应用 - 递归 采用递归算法求解正整数 n 的阶乘 n! Fibon 斐波那契数 求 n 的阶乘的递归函数算法如下 : long fact(int n) { long f; 1 n=1 fib(n)= 1 n=2 fib(n-1)+fib(n-2) n>2 if(n==0) f=1; else f=n*fact(n-1); return f; 2011-10-18 11

进行 fact(4) 调用的系统栈的变化情况 n r n r n r n r n r n r n r n r n r n r 0 r2 1 r2 1 r2 1 r2 2 r2 2 r2 2 r2 2 r2 2 r2 r2 r2 r2 r2 r2 r2 r2 4 r1 4 r1 4 r1 4 r1 4 r1 4 r1 4 r1 4 r1 4 r1 调用 fact(4) 调用 fact() 调用 fact(2) 调用 fact(1) 调用 fact(0) 返回 fact(0) 返回 fact(1) 返回 fact(2) 返回 fact() 返回 fact(4) 2011-10-18 12

函数 fact(4) 的递归调用过程的执行流程 n:4 n: n:2 n:1 n:0 (1) (2) () (4) (5) (6) (7) (8) (9) (10) fact(4) f=4*fact(); f=*fact(2); f=2*fact(1); f=1*fact(0); f=1; (20) (19) (18) (17) (16) (15) (14) (1) (12) (11) return f; return f; return f; return f; return f; 2011-10-18 1

.2 2 ADT 队列 1.. 队列的定义 队列也是一种运算受限的线性表 在这种线性表上, 插入限定在表的某一端进行, 删除限定在表的另一端进行 允许插入的一端称为队尾, 允许删除的一端称为队头 特点 : 队列中数据元素的入队和出队过程是按照 先进 先出 的原则进行的 因此, 队列又称为 先进先出 的线 性表, 简称 FIFO 表 2011-10-18 14

顺序队列 ( MaxSize=5 ) 的几种状态 rear front rear rear 4 4 4 4 D 4 rear rear front C front front 2 2 B 2 2 2 rear 1 0 front A 1 0 front A 1 0 1 0 1 0 (a) (b) (c) (d) (e) (f) 4 2 1 0 (a) 表示空队列, rear=front=0 (b) 元素 A 入队后, rear=1,front=0 (c)b,c 依次入队后, rear=,front=0 (d)a,b,c 依此出队后, rear=front= (e)d 入队后,rear=4, front= (f)d 出队后,rear=front=4 2011-10-18 15

2. ADT 队列 structure Queue object: 零个或多个有穷有序表 Funtions: Queue CreateQ(max_size)::= 创建空队列 Boolean IsFullQ(queue,maxsize)::=if Num(queue)== )==max_size) return Ture else return False Queue AddQ(queue,item ::= if(isfullq(queue)) Queue_full Boolean IsEmptyQ(queue)::= if(queue== ==CreateQ(max_size) ) ) return Ture else return False Element DeleteQ(queue)::= if(isemptyq(queue)) return End Queue else delete e and return item of front 2011-10-18 16

队列的顺序存储表示 Queue CreateQ(max_size)::= #define MAX_SIZE 100 typedef struct { int key; element; element queue[max_size] int rear=-1; int front=-1; Boolean IsEmptyQ(queue)::=front==rear 顺序队列的数据类型定义 2 #define MaxSize < 队列的最大容量 > typedef struct{ ElemType data[maxsize]; int front,rear; SQUEUE; Boolean IsFullQ(queue,maxsize)::=rear== MAX_SIZE-1 2011-10-18 17

队列基本操作 程序 - 入队 void addq(int *rear, element item) { /*add an item to queue*/ if(*rear== MAX_SIZE-1){ queue_full(); return; 程序 -4 出队 element deleteq(int *front, int rear) {/*remove/*remove an element at the fornt of~*/ if(*front== rear) return queue_empty(); return queue[++*front]; queue[++*rear]=item; 2011-10-18 18

循环队列 - 具有五个存储单元 : 2 1 2 1 A rear 2 B A 1 2 B 1 front 2 1 0 0 C 0 C 0 rear D D 4 front 4 front rear 4 front rear 4 front rear 4 (a) (b) (c) (d) (e) (a) 表示空队列, rear= front=0 (b) 元素 A 入队后, rear=1, front=0 (c)b,c,d 依次入队后, rear=4, front=0 (d)a 出队后, front=1,rear=4 (e)b,c,d 出队后, rear= front=4 Addq 实现 :*rear=(*rear+1)%max_size; 0 2011-10-18 19

程序 -5 循环队列的插入 void addq(int front, int *rear,element item) { /*add an item to the queue */ *rear=(*rear+1)%max_size; if(front==*rear){ queue_full(rear); return; queue[*rear]=item; 程序 -6 循环队列的删除 Element deletq(int *front, int rear) { if(*front==rear){ return queue_empty(); *front=(*front+1)% )%MAX_SIZE; return queue[*front]; 2011-10-18 20

. 迷宫问题 1. 允许移动方向表的声明 : typedef struct{ short int vert; short int horiz; offsets; Offsets move[8]; 2. 栈的存储问题 : #define MAX_STACK_SIZE 100 typedef struct{ short int row; [row-1] [col-1] X [row] [col[ col] 方向 :p7: short int col; short int dir; element; element stack[max_stack_size]; 2011-10-18 21

程序 -7 最初的迷宫算法 Initialize a stack to the maze s s entrance coordinates to north; While(stack is not empty) { <row,col,dir>=delete from top of stack; While(there are more moves from current position){ <next_row,next_col>=coordinates of next move; dir=direction of move; if((next_row== ==Exit_row)&&(next_col== ==Exit_col)) success; if(maze[next_row][next_col]==0{ ]==0{ mark[next_row][next_col]=1; ]=1; add<row,col,dir row,col,dir> > to the top of the stack; row=next_row next_row; col=next_col next_col; dir=north; 2011-10-18 22

程序 -8 迷宫搜索函数 void path(void) { int i,row,col,next_row,next_col,dir, found=false; element position; mark[1][1]=1;top=0; stack[0].row=1;stack[0].col=1;stack[0].dir=1; while(top>-1&&!found){ position=delete(&top delete(&top); row=position.row position.row; col=position.col position.col; dir=position.dir position.dir; while(dir<8&&!found){ next_row=row+move[dir].vert row+move[dir].vert; next_col=col+move[dir].horiz col+move[dir].horiz; if(next_row== found=true; ==EXIT_ROW&& && next_col== else if(!maze[next_row][next_col]&& ]&& ==EXIT_COL)!mark[next_row][next_col]){]){ mark[].. mark[next_row][next_col]=1 ]=1 position.row=row;position.col row;position.col=col Add(&top,position); row=next_row;col next_row;col=next_col;dir=0; else ++dir; 2011-10-18 2 If(found){ printf( The path is:\n ); printf( row row col\n ) for(i=0;i<= =0;i<=top;i++) printf( %2d%5d %2d%5d,stack[i].row,stack[i].col); printf( %2d%5d %2d%5d, row,col); printf( %2d%5d %2d%5d,Exit_row,Exit_col); else printf( The maze does t have a path );

.4 表达式求值 例 :x=: x=a/b-c+d*e-a*c; 当 a=4,b=c=2,d=e= 运算的优先级 : 符号运算符优先级结合性 ()[ ] ->. 函数调用 数组元素 结构 17 自左向右 -- ++ 自增 自减 16 自左向右 -- ++! ~ - + & * sizeof 自减 自增 逻辑非 补 一元减或加 求地址 求容量 15 自右向左 (type) 强制类型转换 14 自右向左 * / % 乘 1 自左向右 + - 二元加或减 12 自左向右 << >> 移位 11 自左向右 > >= < <= 关系运算 10 自左向右 ==!= 等于 9 自左向右 & 按位与 8 自左向右 ^ 按位异或 7 自左向右 按位或 6 自左向右 && 逻辑非 5 自左向右 逻辑与 4 自左向右?: 条件 自左向右 = += -= /= *= %= <<= >>= &= ^= = 赋值 2 自右向左, 逗号 1 自左向右 2011-10-18 24

中缀算术表达式 ( (7-2) ) 求值的动态过程 *(7-2)# *(7-2)# (7-2)# 7-2)# -2)# 2)# )# )# # # 运算数栈 2 7 7 7 5 5 15 运算符栈 - - ( ( ( ( ( * * * * * * * # # # # # # # # # # (a) (b) (c) (d) (e) (f) (g) (h) (i) (j) 2011-10-18 25

程序 -9 后缀表达式的求值函数 int eval(void) { precedence token; char symbol; int op1,op2; int n=0; int top=-1; token=get_token(&symbol,&n); while(token==operand) add(&top,symbol- 0 ); else { op2=delete(&top); op1=delete(&top); switch(token) { case plus: add(&top,op1+op2); break; case minus:add(&top,op1-op2);break; case times : add(&top,op1*op2); break; case minus:devide(&top,op1/op2);break; token=get_token(&symbol,&n); return delete(&top); /*return result */ 程序 -10 从输入字符串中取出一个 标记符号的函数 Procedence get_token(char*symbol,int *n) *symbol=expr[(*n)++]; switch(*symbol){ case ( :return lparen; case ) : return rparen; case + :return plus; case - :return minus; case / : return devide; case * :return times; case : return eos; default :return operand; 2011-10-18 26

程序 -11 中缀表达式转换后缀表达式函数 void postfix(void) { char symbol; precedence token; int n=0; int top=0; stack[0]=eos; for(token=get_token(&symbol,&n); token!=eos; token=get_token(&symbol,&n)){ if(token==operand) printf( %c,symbol); else if(token==rparen){ while(stack[top]!=lparen) print_token(delete(%top)); delete(&top); else { while(isp[stack[top]>=icp[token] print_token(delete(%top)); add(&top); while((token=delete(&top))!=eos) printf_token(token); printf( \n ); 2011-10-18 27

中缀表达式转换为等价的后缀表达式 中缀表达式 等价后缀表达式 0./(5 (5 2+1) 0. 5 2 1+/ 2 16-9 (4+) 16 9 4 + - 2 (x+y)/(1-x) x) 2 x y + 1 + 1 x-/ x (25+x) (a (a+b)+b) (a+b)+b) 25 x+a a b+ b+ b+ 2011-10-18 28

.5 多栈和多队列 假定 n 个栈共用一个数组, 可将可用空间, 分成 n 段. 相关声明 : #define MEMORY_SIZE 100 #define MAX_STACKS 10 Element memory[memory_size]; Int top[maz_stacks] Int boundary[max_stacks]; Int n; 数组分割代码 : Top[0]=boundary[0]=-1; For(i=1;i<n;i++) top[i]=boundary[i]=(memory_size/n)*i; Bondary[n]=MEMORY_SIZE-1; 2011-10-18 29

.5 多栈和多队列 程序 -12 向栈 stack_no 中插入 item void add(int i, element item) { if (top[i]==boundary[i+1]) stack_full(i); memory[++top[i]]=item; 程序 -1 从栈 stack_no 中删除元素 void delete(int i) { if (top[i]==boundary[i]) return stack_empty(i); return memory[top[i]--]; 2011-10-18 0

P67 P75 5 迷宫项目程序 ( 选做 ) P81 1,7 习题 2011-10-18 1