1、第三章 链表23-1 改写顺序栈的进栈成员函数Push (x ),要求当栈满时执行一个stackFull ( )操作进行栈满处理。其功能是:动态创建一个比原来的栈数组大二倍的新数组,代替原来的栈数组,原来栈数组中的元素占据新数组的前MaxSize位置。【解答】templatevoid stack : push ( const Type & item ) if ( isFull ( ) ) stackFull ( ); /栈满,做溢出处理 elements +top = item; /进栈 template void stack : stackFull ( ) Type * temp = new
2、 Type 3 * maxSize ; /创建体积大二倍的数组 for ( int i = 0; i = top; i+ ) /传送原数组的数据tempi = elementsi; delete elements; /删去原数组 maxSize *= 3; /数组最大体积增长二倍 elements = temp; /新数组成为栈的数组空间 3-2 铁路进行列车调度时, 常把站台设计成栈式结构的站台,如右图所示。试问: (1) 设有编号为1,2,3,4,5,6的六辆列车, 顺序开入栈式结构的站台, 则可能的出栈序列有多少种? (2) 若进站的六辆列车顺序如上所述, 那么是否能够得到435612,
3、 325641, 154623和135426的出站序列, 如果不能, 说明为什么不能; 如果能, 说明如何得到(即写出进栈或出栈的序列)。【解答】 (1) 可能的不同出栈序列有 种。 (2) 不能得到435612和154623这样的出栈序列。因为若在4, 3, 5, 6之后再将1, 2出栈,则1, 2必须一直在栈中,此时1先进栈,2后进栈,2应压在1上面,不可能1先于2出栈。154623也是这种情况。出栈序列325641和135426可以得到。3562244 4411111111 3 32 32 325 325 3256 32564 3256415344122226 1 1 13 135 *
4、*2 13542 1354263-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 j k,那么在输出序列中,可能出现如下5种情况: i进栈,i出栈,j进栈,j出栈,k进栈,k出栈。此时具有最小值的排在最前面pi位置,具有中间值的排在其后pj位置,具有最大值的排在pk位置,有pi
5、 pj pk, 不可能出现pj pk pi的情形; i进栈,i出栈,j进栈,k进栈,k出栈,j出栈。此时具有最小值的排在最前面pi位置,具有最大值的排在pj位置,具有中间值的排在最后pk位置,有pi pk pj , 不可能出现pj pk pi的情形; i进栈,j进栈,j出栈,i出栈,k进栈,k出栈。此时具有中间值的排在最前面pi位置,具有最小值的排在其后pj位置,有pj pi pk, 不可能出现pj pk pi的情形; i进栈,j进栈,j出栈,k进栈,k出栈,i出栈。此时具有中间值的排在最前面pi 位置,具有最大值的排在其后pj位置,具有最小值的排在pk位置,有pk pi pj, 也不可能出现
6、pj pk pi的情形; i进栈,j进栈,k进栈,k出栈,j出栈,i出栈。此时具有最大值的排在最前面pi 位置,具有中间值的排在其后pj位置,具有最小值的排在pk位置,有pk pj pi, 也不可能出现pj pk pi的情形;0 m-13-4 将编号为0和1的两个栈存放于一个数组空间Vm中,栈底分别处于数组的两端。当第0号栈的栈顶指针top0等于-1时该栈为空,当第1号栈的栈顶指针top1等于m时该栈为空。两个栈均从两端向中间增长。当向第0号栈插入一个新元素时,使top0增1得到新的栈顶位置,当向第1号栈插入一个新元素时,使top1减1得到新的栈顶位置。当top0+1 = top1时或top0
7、 = top1-1时,栈空间满,此时不能再向任一栈加入新的元素。试定义这种双栈(Double Stack)结构的类定义,并实现判栈空、判栈满、插入、删除算法。【解答】bot0 top0 top1 bot1 双栈的类定义如下: #include template class DblStack /双栈的类定义 private: int top2, bot2; /双栈的栈顶指针和栈底指针 Type *elements; /栈数组 int m; /栈最大可容纳元素个数 public: DblStack ( int sz =10 ); /初始化双栈, 总体积m的默认值为10 DblStack ( ) d
8、elete elements; /析构函数 void DblPush ( const Type& x, int i ); /把x插入到栈i的栈顶 int DblPop ( int i ); /退掉位于栈i栈顶的元素 Type * DblGetTop ( int i ); /返回栈i栈顶元素的值 int IsEmpty ( int i ) const return topi = boti; /判栈i空否, 空则返回1, 否则返回0 int IsFull ( ) const return top0+1 = top1; /判栈满否, 满则返回1, 否则返回0 void MakeEmpty ( int
9、 i ); /清空栈i的内容 template DblStack : DblStack ( int sz ) : m(sz), top0 (-1), bot0(-1), top1(sz), bot1(sz) /建立一个最大尺寸为sz的空栈, 若分配不成功则错误处理。 elements = new Typem; /创建栈的数组空间 assert ( elements != NULL ); /断言: 动态存储分配成功与否 template void DblStack : DblPush ( const Type& x, int i ) /如果IsFull ( ),则报错;否则把x插入到栈i的栈顶
10、assert ( !IsFull ( ) ); /断言: 栈满则出错处理,停止执行 if ( i = 0 ) elements +top0 = x; /栈0情形:栈顶指针先加1, 然后按此地址进栈 else elements-top1 = x; /栈1情形:栈顶指针先减1, 然后按此地址进栈 template int DblStack : DblPop ( int i ) /如果IsEmpty ( i ),则不执行退栈,返回0;否则退掉位于栈i栈顶的元素,返回1 if ( IsEmpty ( i ) ) return 0; /判栈空否, 若栈空则函数返回0 if ( i = 0 ) top0-
11、; /栈0情形:栈顶指针减1 else top1+; /栈1情形:栈顶指针加1 return 1; template Type * DblStack : DblGetTop ( int i ) /若栈不空则函数返回该栈栈顶元素的地址。 if ( IsEmpty ( int i ) ) return NULL; /判栈i空否, 若栈空则函数返回空指针 return& elements topi ; /返回栈顶元素的值 template void MakeEmpty ( int i ) if ( i = 0 ) top0 = bot0 = -1; else top1 = bot1 = m; 3-5
12、 写出下列中缀表达式的后缀形式: (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 D) ) )|(C ! | (6) A B C | ! & ! C E isp(OPTR),则ch进OPTR栈,从中缀表达式取下一字符送入ch; 若icp(ch) isp ( ; ), 进OPTR栈, 取下一符号a; +3b操作数 b 进OPND栈, 取下一符号a b; +4*操作符 icp
13、( * ) isp ( + ), 进OPTR栈, 取下一符号a b; + *5(操作符 icp ( ( ) isp ( * ), 进OPTR栈, 取下一符号a b; + * (6c操作数 c 进OPND栈, 取下一符号a b c; + * (7-操作符 icp ( - ) isp ( ( ), 进OPTR栈, 取下一符号a b; + * ( -8d操作数 d 进OPND栈, 取下一符号a b c d; + * ( -9)操作符 icp ( ) ) isp ( - ), 退OPND栈 d, 退OPND 栈 c, 退OPTR栈 -, 计算 c d s1, 结果进 OPND栈a b s1; + *
14、(10同上同上 icp ( ) ) = isp ( ( ), 退OPTR栈(, 对消括号, 取下一符号a b s1; + * 11-操作符 icp ( - ) isp ( * ), 退OPND栈 s1, 退OPND 栈 b, 退OPTR栈 *, 计算 b * s1 s2, 结果进 OPND栈a s2; + 12同上同上 icp ( - ) isp ( ; ), 进OPTR栈, 取下一符号s3 ; -14e操作数 e 进OPND栈, 取下一符号s3 e; -15操作符 icp ( ) isp ( - ), 进OPTR栈, 取下一符号s3 e; -16f操作数 f 进OPND栈, 取下一符号s3
15、e f; -17/操作符 icp ( / ) isp ( - ), 进OPTR栈, 取下一符号s3 s4; - /19g操作数 g 进OPND栈, 取下一符号s3 s4 g; - /20;操作符 icp ( ; ) isp ( / ), 退OPND栈 g, 退OPND 栈 s4, 退OPTR栈 /, 计算 s4 / g s5, 结果 进OPND栈s3 s5; -21同上同上 icp ( ; ) isp ( - ), 退OPND栈 s5, 退OPND 栈 s3, 退OPTR栈 - , 计算 s3 s5 s6, 结 果进OPND栈s6;22同上同上 icp ( ; ) = isp ( ; ), 退
16、OPND栈 s6, 结束;3-8 假设以数组Qm存放循环队列中的元素, 同时以rear和length分别指示环形队列中的队尾位置和队列中所含元素的个数。试给出该循环队列的队空条件和队满条件, 并写出相应的插入(enqueue)和删除(dlqueue)元素的操作。【解答】循环队列类定义 #include template class Queue /循环队列的类定义 public: Queue ( int=10 ); Queue ( ) delete elements; void EnQueue ( Type & item ); Type DeQueue ( ); Type GetFront (
17、); void MakeEmpty ( ) length = 0; /置空队列 int IsEmpty ( ) const return length = 0; /判队列空否 int IsFull ( ) const return length = maxSize; /判队列满否 private: int rear, length; /队尾指针和队列长度 Type *elements; /存放队列元素的数组 int maxSize; /队列最大可容纳元素个数 构造函数 template Queue: Queue ( int sz ) : rear (maxSize-1), length (0)
18、, maxSize (sz) /建立一个最大具有maxSize个元素的空队列。 elements = new TypemaxSize; /创建队列空间 assert ( elements != 0 ); /断言: 动态存储分配成功与否 插入函数 template void Queue : EnQueue ( Type &item ) assert ( ! IsFull ( ) ); /判队列是否不满,满则出错处理 length+; /长度加1rear = ( rear +1) % maxSize; /队尾位置进1 elementsrear = item; /进队列 删除函数 template
19、Type Queue : DeQueue ( ) assert ( ! IsEmpty ( ) ); /判断队列是否不空,空则出错处理 length-; /队列长度减1return elements(rear-length+maxSize) % maxSize; /返回原队头元素值 读取队头元素值函数 template Type Queue : GetFront ( ) assert ( ! IsEmpty ( ) );return elements(rear-length+1+maxSize) % maxSize; /返回队头元素值 3-9 假设以数组Qm存放循环队列中的元素, 同时设置一个
20、标志tag,以tag = 0和tag = 1来区别在队头指针(front)和队尾指针(rear)相等时,队列状态为“空”还是“满”。试编写与此结构相应的插入(enqueue)和删除(dlqueue)算法。【解答】循环队列类定义 #include template class Queue /循环队列的类定义 public: Queue ( int=10 ); Queue ( ) delete Q; void EnQueue ( Type & item ); Type DeQueue ( ); Type GetFront ( ); void MakeEmpty ( ) front = rear =
21、 tag = 0; /置空队列 int IsEmpty ( ) const return front = rear & tag = 0; /判队列空否 int IsFull ( ) const return front = rear & tag = 1; /判队列满否 private: int rear, front, tag; /队尾指针、队头指针和队满标志 Type *Q; /存放队列元素的数组 int m; /队列最大可容纳元素个数 构造函数 template Queue: Queue ( int sz ) : rear (0), front (0), tag(0), m (sz) /建立一个最大具有m个元素的空队列。 Q = new Typem; /创建队列空间 assert ( Q != 0 ); /断言: 动态存储分配成功与否 插入函数 template void Queue : EnQueue ( Type &item ) assert ( ! IsFull ( ) ); /判队列是否不满,满则出错处理 rear = ( rear + 1 ) % m; /队尾位置进1, 队尾指针指示实际队尾位置 Qrear = item;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1