《数据结构》习题汇编03 第三章 栈和队列 试题(答案)

  • 格式:doc
  • 大小:156.50 KB
  • 文档页数:7

第三章 栈和队列

一、单项选择题

参考答案: 1. A 2. B 3. C 4. A 5. B

6. B 7. D 8. D 9. C 10. A

11. D 12. A 13. A 14. D 15. C

二、填空题

参考答案:

1. 先进后出 2. 先进先出 3. 队尾,队头 4. 栈顶指针 5. 栈顶指针

6. MaxSize-1 7. top==0 8. 空栈 9. 栈顶指针 10. p->link=top,top=p

11. top=top->link 12. Q.front==Q.rear 13. (Q.rear+1)%MaxSize==Q.front

14. 队尾指针 15. 空,只含有一个结点

16. front == rear && front != NULL或者front == rear && rear != NULL

17. 两端 18. 3x2+*5- 19. 15 20. 3

三、判断题

参考答案: 1. 是 2. 是 3. 否 4. 是 5. 是

6. 否 7. 否 8. 是 9. 否 10. 否

11. 否 12. 是 13. 否 14. 是 15. 否

16. 否

四、运算题

参考答案:

1. 根据以上规则,给出计算中缀表达式a + b * c – d / e时两个栈的变化。

步 扫描项 项类型 动 作 OPND栈 OPTR栈

0 OPTR栈与OPND栈初始化, ‘#’ 进OPTR栈,

取第一个符号 #

1 a 操作数 a进OPND栈, 取下一符号 a #

2 + 操作符 icp (‘+’ ) > isp (‘#’ ), 进OPTR栈, 取下一符号 a # +

3 b 操作数 b进OPND栈, 取下一符号 a b # +

4 * 操作符 icp (‘*’ ) > isp (‘+’ ), 进OPTR栈, 取下一符号 a b # + *

5 c 操作数 c进OPND栈, 取下一符号 a b c # + *

6 - 操作符 icp (‘-’ ) < isp (‘*’ ), 退OPND栈 ‘c’,

退OPND

栈 ‘b’, 退OPTR栈 ‘*’, 计算 b * c → s1,

结果

进OPND栈 a s1 # +

7 同上 同上 icp (‘-’ ) < isp (‘+’ ), 退OPND栈 ‘s1’,

退OPND

栈 ‘a’, 退OPTR栈 ‘+’, 计算 a * s1 →

s2, 结果

进OPND栈 s2 # 8 同上 同上 icp (‘-’ ) > isp (‘#’ ), 进OPTR栈, 取下一符号 s2 # -

9 d 操作数 d进OPND栈, 取下一符号 s2 d # -

10 / 操作符 icp (‘/’ ) > isp (‘-’ ), 进OPTR栈, 取下一符号 s2 d # - /

11 e 操作数 e进OPND栈, 取下一符号 s2 d e # - /

12 # 操作符 icp (‘#’ ) < isp (‘/’ ), 退OPND栈 ‘e’,

退OPND

栈 ‘d’, 退OPTR栈 ‘/’, 计算 d / e →

s5, 结果

进OPND栈 s2 s3 # -

13 同上 同上 icp (‘#’ ) < isp (‘-’ ), 退OPND栈 ‘s3’,

退OPND

栈 ‘s2’, 退OPTR栈 ‘-’, 计算 s2 – s3 →

s4, 结

果进OPND栈 s4 #

14 同上 同上  icp (‘#’ ) == isp (‘#’ ), 退OPND栈 ‘s4’, 结束 #

2. 利用运算符优先数,画出将中缀表达式a + b * c - d / e 改为后缀表达式时运算符栈OPTR的变化。

步 扫描项 项类型 动 作 OPTR栈 输 出

0 '#' 进栈, 读下一符号 #

1 a 操作数 直接输出, 读下一符号 # a

2 + 操作符 isp ( '#' ) < icp ( '+' ), 进栈, 读下一符号 # + a

3 b 操作数 直接输出, 读下一符号 # + a b

4 * 操作符 isp ( '+' ) < icp ( '*' ), 进栈, 读下一符号 # + * a b

5 c 操作数 直接输出, 读下一符号 # + * a b c

6 - 操作符 isp ( '*' ) > icp ( '-' ), 退栈输出 '*' # + a b c *

7 同上 同上 isp ( '+' ) > icp ( '-' ), 退栈输出 '+' # a b c * +

8 同上 同上 isp ( '#' ) < icp ( '-' ), 进栈, 读下一符号 # - a b c * +

9 d 操作数 直接输出, 读下一符号 # - a b c * + d

10 / 操作符 isp ( '-' ) < icp ( '/' ), 进栈, 读下一符号 # - / a b c * + d

11 e 操作数 直接输出, 读下一符号 # - / a b c * + d e

12 # 操作符 isp ( '/' ) > icp ( '#' ), 退栈输出 '/' # - a b c * + d e /

1同上 同上 isp ( '-' ) > icp ( '#' ), 退# a b c * + d 3 栈输出 '-' e / -

14 同上 同上 isp ( '#' ) == icp ( '#' ), 结束 # a b c * + d e / -

3. 画出对后缀算术表达式a b c * + d e / - 求值时运算对象栈OPND的变化

步 扫描项 项类型 动 作 OPND栈

1

置空栈 空

2 a

操作数 进栈 a

3 b 操作数 进栈 a b

4 c 操作数 进栈 a b c

5 * 操作符 c、b退栈,计算b * c,结果s1进栈 a s1

6 + 操作符 s1、a退栈,计算a + s1,结果s2进栈 s2

7 d 操作数 进栈 s2 d

8 e 操作数 进栈 s2 d e

9 / 操作符 e、d退栈,计算d / e,结果s3进栈 s2 s3

10 - 操作符 s3、s2退栈,计算s2 - s3,结果s4进 s4

11 # 操作符 结束,在栈顶得到运算结果

4. 将二项式 (a + b) i 展开, 其系数构成杨辉三角形。画出当n = 3的情况下,在打印过程中队列的变化。

步 n s Q→t s+t→Q t→s 输出s 队列Q的变化

(0) (1) (2) (3) (4) (5)

0 0 【1 1 0】

1 1 0 1 1 1 1 【1 0 1】

2 1 1 2 1 1 【0 1 2】

3 1 0 1 0 ― 【1 2 1】

0 0】 【1 2 1

4 2 0 1 1 1 1 0 1】 【2 1

5 1 2 3 2 2 0 1 3】 【1

6 2 1 3 1 1 【0 1 3 3】

7 1 0 1 0 ― 【1 3 3 1】

0 【1 3 3 1 0】

8 3 0 1 1 1 1 1】 【3 3 1 0

9 1 3 4 3 3 1 4】 【3 1 0

10 3 3 6 3 3 1 4 6】 【1 0

11 3 1 4 1 1 1 4 6 4】 【0

12 1 0 1 0 ― 【1 4 6 4 1】

5. stack

6. char

7. 利用"栈"作为辅助存储,将队列中的元素进行逆置.

五、算法分析题

参考答案:

1. 本算法的功能是判断一个字符数组(字符串)是否回文,即正读与反读都一样的字符串。

针对A[ ] = {m, a, d, a, m, i, m, a, d, a, m },它先将串中的字符逐个进栈,再将栈中存放的字符逐个出栈,与串中的字符从头进行比较,若发现不等,则停止比较,返回0,表示该字符串不是回文。若所有栈中字符与串中字符都相等,则函数返回1,表示该字符串是回文。

2. 本算法的功能是将单链表逆置,即将链表中各结点的链接顺序逆转。

针对题中的输入实例:{ u, n, i, v, e, r, s, i, t, y },将其逐个进栈后,从栈顶看,顺序为 { y, t, i, s, r, e, v, i, n, u }。顺序出栈后,链入结果单链表的链尾,最终得到的单链表中各结点中数据的逻辑顺序变为:{ y, t, i, s, r, e, v, i, n, u }。

六、算法设计题

参考答案:

1. 循环队列的定义

template class Queue { //循环队列的类定义

public:

Queue ( int=10 );

int EnQueue ( T x );

int DeQueue ( T& x );

private:

int rear, front, tag; //队尾指针、队头指针和队满标志

T *Q; //存放队列元素的数组

int m; //队列最大可容纳元素个数

}

template

int Queue :: EnQueue ( T x ) { //插入函数

if ( front == rear && tag == 1 ) return 0; //判队列是否满,满则返回0

rear = ( rear + 1 ) % m; //队尾进1, 队尾指针指示实际队尾位置

Q[rear] = item; //进队列

tag = 1; //标志改1,表示队列不空

}

template

int Queue :: DeQueue ( T& x ) { //删除函数

if ( front == rear && tag == 0 ) return 0; //判断队列是否不空,空则返回0

front = ( front + 1 ) % m; //队头进1, 队头指针指示实际队头的前一位置

tag = 0; //标志改0, 表示栈不满

x = Q[front]; //返回原队头元素的值

return 1;