slide1 n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
(第五讲) PowerPoint Presentation
Download Presentation
(第五讲)

Loading in 2 Seconds...

play fullscreen
1 / 22

(第五讲) - PowerPoint PPT Presentation


  • 142 Views
  • Uploaded on

数据结构. (第五讲). 绍兴文理学院. 计算机系计算机应用教研室. 为什么在算术表达式中能 先 乘除 后 加减运算?. TKS. 2. 00:53. 第 3 章 栈和队列( 1 ). 一、教学目的: 明确栈的有关概念;掌握栈的逻辑结构和存储结构,掌握顺序和链式栈的基本操作;掌握栈的初步应用。. 二、教学重点: 栈的 LIFO 的结构和操作特点;栈的逻辑结构和存储结构,顺序和链式栈的基本操作;栈的初步应用;算法设计训练。. 三、教学难点: 栈的 LIFO 的有关概念和操作;栈的初步应用。算法实现 能力的训练。 四、教学过程:. §3.1 栈 (stack).

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about '(第五讲)' - daria


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
slide1

数据结构

(第五讲)

绍兴文理学院

计算机系计算机应用教研室

slide3

第3章 栈和队列(1)

一、教学目的:明确栈的有关概念;掌握栈的逻辑结构和存储结构,掌握顺序和链式栈的基本操作;掌握栈的初步应用。

二、教学重点:栈的LIFO的结构和操作特点;栈的逻辑结构和存储结构,顺序和链式栈的基本操作;栈的初步应用;算法设计训练。

三、教学难点:栈的LIFO的有关概念和操作;栈的初步应用。算法实现能力的训练。

四、教学过程:

slide4

§3.1 栈(stack)

an

栈顶

a2

a1

栈底

TKS

4

§3.1.1 栈的类型定义

1、定义:栈是限定仅在表尾进行插入或删除操作的线性表。

表尾端称为栈顶(top),表头端称为栈底(bottom),不含元素的空表称为空栈。

2、栈的逻辑结构及进出栈

S=(a1,a2,...,ai-1,ai,ai+1,…,an )

删除

插入

出栈

进栈

栈的特点后进先出

LIFO

第一个进栈的元素在栈底,

最后一个进栈的元素在栈顶,

第一个出栈的元素为栈顶元素,

最后一个出栈的元素为栈底元素

00:53

slide5

3、栈的抽象数据类型定义(简讲)

TKS

5

ADT Stack

{数据对象:D={ai|ai ∈ElemSet, i=1,2,...,n, n≥0}

数据关系:R1={<ai-1, ai >| ai-1, ai∈D, i=2,...,n}

约定an端为栈顶,a1 端为栈底。

基本操作:

InitStack(&S)

操作结果:构造一个空栈 S。

DestroyStack(&S)

初始条件:栈 S 已存在。

操作结果:栈 S 被销毁。

ClearStack(&S)

初始条件:栈 S 已存在。

操作结果:将 S 清为空栈。

00:53

slide6

StackEmpty(S)

… …

a1

a2

TKS

6

初始条件:栈 S 已存在。

操作结果:若栈 S 为空栈,则返回 TRUE,否则 FALE。

StackLength(S)

初始条件:栈 S 已存在。

操作结果:返回 S 的元素个数,即栈的长度。

GetTop(S, &e)

初始条件:栈 S 已存在且非空。

操作结果:用 e 返回 S 的栈顶元素。

an

00:53

slide7

Push(&S,e)

… …

a1

a2

an

… …

an-1

a2

a1

TKS

7

初始条件:栈 S 已存在。

操作结果:插入元素 e 为新的栈顶元素。

e

Pop(&S, &e)

初始条件:栈 S 已存在且非空。

操作结果:删除 S 的栈顶元素,并用 e 返回其值。

a

}ADT Stack

00:53

slide8

§3.1.2 顺序栈的表示和实现

TKS

8

1、结构定义

#define size 256

struct sqstack

{ selemtype *base;

int top;

int stacksize;

};

2、栈顶指针top与栈中数据元素的关系

top=-1

空栈

top=-1

空栈

top=0

1个元素

top=4

5个元素

top=2

3个元素

3、初始化

构造一个空栈:首先建立栈空间,然后初始化栈顶指针。

int InitSqStack(sqstack &s)

{ s.base=new selemtype[size];

s.top=-1; s.stacksize=size;

return 1;

}

00:53

slide9

4、入栈

5、出栈

TKS

9

int push(sqstack

&s,selemtype e)

{ if(s.top==SIZE-1) return 0;

// 栈满不能入栈

s.top++;

s.base[s.top]=e;

return 1;

}

int pop(sqstack &s,

selemtype &e)

{ if(s.top==-1) return 0;

// 栈空不能出栈

e=s.base[s.top]

s.top--;

return 1;

}

顺序栈的基本操作S5_1

6、取栈顶元素

int gettop(sqstack s,selemtype &e)

{ if(s.top==-1) return 0; // 栈空

e=s.base[s.top];

}

00:53

slide10

§3.1.3 链栈的表示和实现

Data next

top

an

栈顶

an-1

a1

栈底

TKS

10

1、链栈概述

(1) 概念

用链式存储结构实现的栈称为链栈。通常链栈用单链表表示,因此其结点结构与单链表的结构相同。

(2)结构定义

typedef struct stacknode

{ datatype data;

stacknode *next;

} *linkstack;

说明 top为栈顶指针:

linkStack top ;

(3) 入栈和出栈操作

00:53

slide11

2、链栈的基本操作

(1) 初始化

构造一个不带头结点的空栈

int initstack(linkstack &s)

{ s=NULL;

return 1;

}

an

an-1

top

栈顶

a1

栈底

TKS

11

(2) 入栈

int push(linkstack &top,

datatype e)

{ stacknode *s;

s=new stacknode;

s

s->data=e;

top

e

s->next=top;

top=s;

return 1;

}

00:53

slide12

(3) 出栈

e

an

an-1

top

栈顶

a1

栈底

TKS

12

int pop(linkstack &top, datatype &e)

{ linkstack p;

if(top==NULL) return 0;

e=top->data;

an

p=top;

top=top->next;

p

top

delete p;

栈顶

return 1;

}

00:53

slide13

§3.2 栈的应用举例

TKS

13

§3.2.1 数制转换

对于输入的任意一个非负十进制数,显示输出与其等值的八进制数。

1、转换原理

N = (N div d)×d + N mod d

N:十进制数,div:整除运算,mod:求余运算;(1348)10=283+582+08+4=(2504)8

N N div 8 N mod 8

1348 168 4

168 21 0

21 2 5

2 0 2

00:53

slide14

2、算法描述

TKS

14

void conversion()

{int n; sqstack s;

s=initstack(); // 建空栈

cin>>n; // 输入一个非负十进制整数

while(n!=0) // n不等于零循环

{push(s,n%8); // n/8 余数进栈

n=n/8; // 整除运算

}

printf("\n");

while(!stackempty(s)) // 输出存放在栈中的8进制数位

{pop(s,n);

printf("%d",n);

}

}

算法3.8 对于输入的任意一个非负十进制

数,显示输出与其等值的 八进制数。S5_2

00:53

slide15

§3.2.2 括号的匹配

TKS

15

1、问题描述

假设在表达式中 ([ ]( ) )或[([ ][ ])]等为正确的格式,[ ( ])或 ( ( ) )或 ( ( ) ])均为不正确的格式。

则 检验括号是否匹配的方法可用“期待的急迫程度”这个概念来描述。

例如:考虑下列括号序列:

[ ( [ ] [ ] ) ]

1 2 3 4 5 6 7 8

分析可能出现的不匹配的情况:

  • 到来的右括弧并非是所“期待”的;
  • 到来的是“不速之客”;
  • 直到结束,也没有到来所“期待”的括弧。

00:53

slide16

2、算法的设计思想

TKS

16

  • 凡出现左括弧,则进栈;
  • 凡出现右括弧,首先检查栈是否空
  • 若栈空,则表明该“右括弧”多余,
  • 否则和栈顶元素比较,
  • 若相匹配,则“左括弧出栈”,
  • 否则表明不匹配。
  • 表达式检验结束时,
  • 若栈空,则表明表达式中匹配正确,
  • 否则表明“左括弧”有余。

3、算法描述

00:53

slide17

int matching(string exp)

TKS

17

{LinkStack top=NULL; int state=1,i=0;char e;

while(i<exp.size()&&state)

{switch(exp[i])

{case '[': top=push(top,exp[i]);break;

case '(': top=push(top,exp[i]);break;

case ')': if(top!=NULL&&top->data=='(') top=pop(top,e);

else state=0;

break;

case ']': if(top!=NULL&&top->data=='[') top=pop(top,e);

else state=0;

break;

}

i++;

}

算法3.9 括号的匹配S5_3

if(top==NULL&&state) return 1;

return 0;

}

00:53

slide18

§3.2.3 表达式求值

TKS

18

1、分析

一般采用“算符优先法”。使用两个工作栈,一个称为OPTR栈,用来寄存运算符;另一个称为OPND栈,用来寄存操作数或运算结果。

操作数为常量或变量。

把运算符和界限符((、)、#)统称为运算符,任意两个相继出现的运算符θ1和θ2 之间的优先关系,至多是下面3种关系之一:

θ1 < θ2 θ1的优先权低于θ2

θ1 = θ2 θ1的优先权等于θ2

θ1 > θ2 θ1的优先权高于θ2

下表定义了运算符之间的这种优先关系

00:53

slide19

运算符之间的优先关系

θ2

θ1

+

*

/

(

)

#

+

>

>

<

<

<

>

>

>

>

<

<

<

>

>

*

>

>

>

>

<

>

>

/

>

>

>

>

<

>

>

(

<

<

<

<

<

)

>

>

>

>

>

>

#

<

<

<

<

<

TKS

19

▲ 说明:相同的运算符出现 θ1> θ2 的,表示表达式是从左向右运算,θ1是相对在左边的运算符,θ2是相对在右边的运算符。

2、算法思想

00:53

slide20

(1)建立并初始化OPTR栈和OPND栈,将表达式起始符“#”压入OPTR栈。(1)建立并初始化OPTR栈和OPND栈,将表达式起始符“#”压入OPTR栈。

TKS

20

(2)依次读入表达式中每个字符ch,循环执行(3)至(5),直至求出整个表达式的值为止。

(3) 取出OPTR的栈顶元素,当OPTR的栈顶元素和当前读入的字符ch均为“#”时,整个表达式求值完毕,这时OPND的栈顶元素为表达式的值。

(4) 若ch不是运算符,则压入OPND栈,读人下一字符ch。

(5) 若ch是运算符,则根据OPTR的栈顶元素和ch的优先权比较结果,做以下不同的处理。

① 若是小于,则ch压入OPTR栈,读人下一字符ch。

② 若是大于,则弹出OPTR栈顶的运算符,从OPND栈弹出两个数,进行相应运算,结果压入OPND栈。

③ 若是等于,则OPTR的栈顶元素是“(”且ch是“)”,这时弹出OPTR栈顶的“(”,相当于去掉括号,然后读人下一字符ch。

00:53

slide21

3、例3.1 利用“算符优先法”计算算术表达式3*(7-2)值的操作过程

序号 OPTR栈 OPND栈 输入字符 操作

TKS

21

1 #

3*(7-2)#

push(OPND,3)

2 # 3

*(7-2)#

push(OPTR,’*’)

3 #*3

(7-2)#

push(OPTR,’(’)

push(OPND,7)

4 #*(3

7-2)#

push(OPTR,’-’)

5 #*(3 7

-2)#

push(OPND,2)

6 #*(-3 7

2)#

7 #*(-3 7 2

)#

pop(OPND,2) pop(OPND,7) pop(OPTR,’-’)

operate(’7’,’-’,’2’) push(OPND,5)

pop(OPTR,’(’)

{消去一对括号}

8 #*( 3 5

)#

9 #* 3 5

#

pop(OPND,5) pop(OPND,3) pop(OPTR,’*’)

operate(’3’,’*’,’5’) push(OPND,15)

10 #15

#

RETURN(GETTOP(OPND)15)

4、算法3.10 表达式求值 (思考题)

00:53

slide22

TKS

22

五、作业:

1、书面作业:P69:1中:(1)、(2)、(4)、(5)、(6)、

(8)、(9)、(10)

2、上机编程: (数据结构编程练习)中 8831、8832、8833

00:53