第三章 链表2Word文档格式.docx
- 文档编号:20316151
- 上传时间:2023-01-21
- 格式:DOCX
- 页数:26
- 大小:47.54KB
第三章 链表2Word文档格式.docx
《第三章 链表2Word文档格式.docx》由会员分享,可在线阅读,更多相关《第三章 链表2Word文档格式.docx(26页珍藏版)》请在冰豆网上搜索。
的序列)。
【解答】
(1)可能的不同出栈序列有种。
(2)不能得到435612和154623这样的出栈序列。
因为若在4,3,5,6之后再将1,2出栈,则1,2必须一直在栈中,此时1先进栈,2后进栈,2应压在1上面,不可能1先于2出栈。
154623也是这种情况。
出栈序列325641和135426可以得到。
3
5
6
2
4
4
1
33232325325325632564325641
1113135********213542135426
3-3试证明:
若借助栈可由输入序列1,2,3,…,n得到一个输出序列p1,p2,p3,…,pn(它是输入序列的某一种排列),则在输出序列中不可能出现以下情况,即存在i<
j<
k,使得pj<
pk<
pi。
(提示:
用反证法)
因为借助栈由输入序列1,2,3,…,n,可得到输出序列p1,p2,p3,…,pn,如果存在下标i,j,k,满足i<
k,那么在输出序列中,可能出现如下5种情况:
①i进栈,i出栈,j进栈,j出栈,k进栈,k出栈。
此时具有最小值的排在最前面pi位置,具有中间值的排在其后pj位置,具有最大值的排在pk位置,有pi<
pj<
pk,不可能出现pj<
pi的情形;
②i进栈,i出栈,j进栈,k进栈,k出栈,j出栈。
此时具有最小值的排在最前面pi位置,具有最大值的排在pj位置,具有中间值的排在最后pk位置,有pi<
pj,不可能出现pj<
③i进栈,j进栈,j出栈,i出栈,k进栈,k出栈。
此时具有中间值的排在最前面pi位置,具有最小值的排在其后pj位置,有pj<
pi<
④i进栈,j进栈,j出栈,k进栈,k出栈,i出栈。
此时具有中间值的排在最前面pi位置,具有最大值的排在其后pj位置,具有最小值的排在pk位置,有pk<
pj,也不可能出现pj<
⑤i进栈,j进栈,k进栈,k出栈,j出栈,i出栈。
此时具有最大值的排在最前面pi位置,具有中间值的排在其后pj位置,具有最小值的排在pk位置,有pk<
pi,也不可能出现pj<
0m-1
3-4将编号为0和1的两个栈存放于一个数组空间V[m]中,栈底分别处于数组的两端。
当第0号栈的栈顶指针top[0]等于-1时该栈为空,当第1号栈的栈顶指针top[1]等于m时该栈为空。
两个栈均从两端向中间增长。
当向第0号栈插入一个新元素时,使top[0]增1得到新的栈顶位置,当向第1号栈插入一个新元素时,使top[1]减1得到新的栈顶位置。
当top[0]+1==top[1]时或top[0]==top[1]-1时,栈空间满,此时不能再向任一栈加入新的元素。
试定义这种双栈(DoubleStack)结构的类定义,并实现判栈空、判栈满、插入、删除算法。
bot[0]top[0]top[1]bot[1]
双栈的类定义如下:
#include<
assert.h>
template<
classDblStack{//双栈的类定义
private:
inttop[2],bot[2];
//双栈的栈顶指针和栈底指针
Type*elements;
//栈数组
intm;
//栈最大可容纳元素个数
public:
DblStack(intsz=10);
//初始化双栈,总体积m的默认值为10
~DblStack(){delete[]elements;
}//析构函数
voidDblPush(constType&
x,inti);
//把x插入到栈i的栈顶
intDblPop(inti);
//退掉位于栈i栈顶的元素
Type*DblGetTop(inti);
//返回栈i栈顶元素的值
intIsEmpty(inti)const{returntop[i]==bot[i];
}//判栈i空否,空则返回1,否则返回0
intIsFull()const{returntop[0]+1==top[1];
}//判栈满否,满则返回1,否则返回0
voidMakeEmpty(inti);
//清空栈i的内容
}
DblStack<
DblStack(intsz):
m(sz),top[0](-1),bot[0](-1),top[1](sz),bot[1](sz){
//建立一个最大尺寸为sz的空栈,若分配不成功则错误处理。
elements=newType[m];
//创建栈的数组空间
assert(elements!
=NULL);
//断言:
动态存储分配成功与否
voidDblStack<
DblPush(constType&
x,inti){
//如果IsFull(),则报错;
否则把x插入到栈i的栈顶
assert(!
IsFull());
//断言:
栈满则出错处理,停止执行
if(i==0)elements[++top[0]]=x;
//栈0情形:
栈顶指针先加1,然后按此地址进栈
elseelements[--top[1]]=x;
//栈1情形:
栈顶指针先减1,然后按此地址进栈
}
intDblStack<
DblPop(inti){
//如果IsEmpty(i),则不执行退栈,返回0;
否则退掉位于栈i栈顶的元素,返回1
if(IsEmpty(i))return0;
//判栈空否,若栈空则函数返回0
if(i==0)top[0]--;
//栈0情形:
栈顶指针减1
elsetop[1]++;
//栈1情形:
栈顶指针加1
return1;
Type*DblStack<
DblGetTop(inti){
//若栈不空则函数返回该栈栈顶元素的地址。
if(IsEmpty(inti))returnNULL;
//判栈i空否,若栈空则函数返回空指针
return&
elements[top[i]];
//返回栈顶元素的值
}
template<
voidMakeEmpty(inti){
if(i==0)top[0]=bot[0]=-1;
elsetop[1]=bot[1]=m;
3-5写出下列中缀表达式的后缀形式:
(1)A*B*C
(2)-A+B-C+D
(3)A*-B+C
(4)(A+B)*D+E/(F+A*D)+C
(5)A&
&
B||!
(E>
F)/*注:
按C++的优先级*/
(6)!
(A&
!
((B<
C)||(C>
D)))||(C<
E)
(1)AB*C*
(2)A-B+C-D+
(3)AB-*C+
(4)AB+D*EFAD*+/+C+
(5)AB&
EF>
||
(6)ABC<
CD>
||!
&
CE<
3-6根据课文中给出的优先级,回答以下问题:
(1)在函数postfix中,如果表达式e含有n个运算符和分界符,问栈中最多可存入多少个元素?
(2)如果表达式e含有n个运算符,且括号嵌套的最大深度为6层,问栈中最多可存入多少个元素?
(1)在函数postfix中,如果表达式e含有n个运算符和分界符,则可能的运算对象有n+1个。
因此在利用后缀表达式求值时所用到的运算对象栈中最多可存入n+1个元素。
(2)同上。
3-7试利用运算符优先数法,画出对如下中缀算术表达式求值时运算符栈和运算对象栈的变化。
a+b*(c-d)-e↑f/g
设在表达式计算时各运算符的优先规则如上一题所示。
因为直接对中缀算术表达式求值时必须使用两个栈,分别对运算符和运算对象进行处理,假设命名运算符栈为OPTR(operator的缩写),运算对象栈为OPND(operand的缩写),下面给出对中缀表达式求值的一般规则:
(1)建立并初始化OPTR栈和OPND栈,然后在OPTR栈中压入一个“;
”
(2)从头扫描中缀表达式,取一字符送入ch。
(3)当ch不等于“;
”时,执行以下工作,否则结束算法。
此时在OPND栈的栈顶得到运算结果。
①如果ch是运算对象,进OPND栈,从中缀表达式取下一字符送入ch;
②如果ch是运算符,比较ch的优先级icp(ch)和OPTR栈顶运算符isp(OPTR)的优先级:
若icp(ch)>
isp(OPTR),则ch进OPTR栈,从中缀表达式取下一字符送入ch;
若icp(ch)<
isp(OPTR),则从OPND栈退出一个运算符作为第2操作数a2,再退出一个运算符作为第1操作数a1,从OPTR栈退出一个运算符θ形成运算指令(a1)θ(a2),执行结果进OPND栈;
若icp(ch)==isp(OPTR)且ch==“)”,则从OPTR栈退出栈顶的“(”,对消括号,然后从中缀表达式取下一字符送入ch;
根据以上规则,给出计算a+b*(c-d)-e↑f/g时两个栈的变化。
步序
扫描项
项类型
动作
OPND栈变化
OPTR栈变化
OPTR栈与OPND栈初始化,‘;
’进OPTR栈,
取第一个符号
;
a
操作数
a进OPND栈,取下一符号
+
操作符
icp(‘+’)>
isp(‘;
’),进OPTR栈,取下一符号
+
b
b进OPND栈,取下一符号
ab
*
icp(‘*’)>
isp(‘+’),进OPTR栈,取下一符号
+*
(
icp(‘(’)>
isp(‘*’),进OPTR栈,取下一符号
+*(
c
c进OPND栈,取下一符号
abc
7
-
icp(‘-’)>
isp(‘(’),进OPTR栈,取下一符号
+*(-
8
d
d进OPND栈,取下一符号
abcd
9
)
icp(‘)’)<
isp(‘-’),退OPND栈‘d’,退OPND
栈‘c’,退OPTR栈‘-’,计算c–d→s1,结果进
OPND栈
abs1
10
同上
icp(‘)’)==isp(‘(’),退OPTR栈‘(’,对消括号,
取下一符号
+*
11
icp(‘-’)<
isp(‘*’),退OPND栈‘s1’,退OPND
栈‘b’,退OPTR栈‘*’,计算b*s1→s2,结果进
as2
+
12
isp(‘+’),退OPND栈‘s2’,退OPND
栈‘a’,退OPTR栈‘+’,计算a*s2→s3,结果
进OPND栈
s3
13
s3
-
14
e
e进OPND栈,取下一符号
s3e
15
↑
icp(‘↑’)>
isp(‘-’),进OPTR栈,取下一符号
-↑
16
f
f进OPND栈,取下一符号
s3ef
17
/
icp(‘/’)<
isp(‘↑’),退OPND栈‘f’,退OPND
栈‘e’,退OPTR栈‘↑’,计算e↑f→s4,结果
s3s4
18
icp(‘/’)>
-/
19
g
g进OPND栈,取下一符号
s3s4g
20
icp(‘;
’)<
isp(‘/’),退OPND栈‘g’,退OPND
栈‘s4’,退OPTR栈‘/’,计算s4/g→s5,结果
s3s5
21
isp(‘-’),退OPND栈‘s5’,退OPND
栈‘s3’,退OPTR栈‘-’,计算s3–s5→s6,结
果进OPND栈
s6
22
’)==isp(‘;
’),退OPND栈‘s6’,结束
3-8假设以数组Q[m]存放循环队列中的元素,同时以rear和length分别指示环形队列中的队尾位置和队列中所含元素的个数。
试给出该循环队列的队空条件和队满条件,并写出相应的插入(enqueue)和删除(dlqueue)元素的操作。
循环队列类定义
template<
classQueue{//循环队列的类定义
public:
Queue(int=10);
~Queue(){delete[]elements;
voidEnQueue(Type&
item);
TypeDeQueue();
TypeGetFront();
voidMakeEmpty(){length=0;
}//置空队列
intIsEmpty()const{returnlength==0;
}//判队列空否
intIsFull()const{returnlength==maxSize;
}//判队列满否
private:
intrear,length;
//队尾指针和队列长度
//存放队列元素的数组
intmaxSize;
//队列最大可容纳元素个数
构造函数
Queue<
Queue(intsz):
rear(maxSize-1),length(0),maxSize(sz){
//建立一个最大具有maxSize个元素的空队列。
elements=newType[maxSize];
//创建队列空间
assert(elements!
=0);
插入函数
voidQueue<
EnQueue(Type&
item){
assert(!
IsFull());
//判队列是否不满,满则出错处理
length++;
//长度加1
rear=(rear+1)%maxSize;
//队尾位置进1
elements[rear]=item;
//进队列
删除函数
TypeQueue<
DeQueue(){
IsEmpty());
//判断队列是否不空,空则出错处理
length--;
//队列长度减1
returnelements[(rear-length+maxSize)%maxSize];
//返回原队头元素值
读取队头元素值函数
GetFront(){
returnelements[(rear-length+1+maxSize)%maxSize];
//返回队头元素值
3-9假设以数组Q[m]存放循环队列中的元素,同时设置一个标志tag,以tag==0和tag==1来区别在队头指针(front)和队尾指针(rear)相等时,队列状态为“空”还是“满”。
试编写与此结构相应的插入(enqueue)和删除(dlqueue)算法。
classQueue{//循环队列的类定义
~Queue(){delete[]Q;
voidMakeEmpty(){front=rear=tag=0;
}//置空队列
intIsEmpty()const{returnfront==rear&
tag==0;
}//判队列空否
intIsFull()const{returnfront==rear&
tag==1;
}//判队列满否
intrear,front,tag;
//队尾指针、队头指针和队满标志
Type*Q;
//存放队列元素的数组
//队列最大可容纳元素个数
rear(0),front(0),tag(0),m(sz){
//建立一个最大具有m个元素的空队列。
Q=newType[m];
//创建队列空间
assert(Q!
rear=(rear+1)%m;
//队尾位置进1,队尾指针指示实际队尾位置
Q[rear]=item;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第三章 链表2 第三 链表