资源预览内容
第1页 / 共16页
第2页 / 共16页
第3页 / 共16页
第4页 / 共16页
第5页 / 共16页
第6页 / 共16页
第7页 / 共16页
第8页 / 共16页
第9页 / 共16页
第10页 / 共16页
亲,该文档总共16页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第3章 栈和队列 一、基础知识题3.1 有五个数依次进栈:1,2,3,4,5。在各种出栈的序列中,以3,4先出的序列有哪几个。(在之前出栈)。【解答】34215 ,34251, 345213.2 铁路进行列车调度时,常把站台设计成栈式结构,若进站的六辆列车顺序为:1,2,3,4,5,6, 那么是否能够得到435612, 325641, 154623和135426的出站序列,如果不能,说明为什么不能; 如果能, 说明如何得到(即写出进栈或出栈的序列)。 【解答】输入序列为123456,不能得出435612和154623。不能得到435612的理由是,输出序列最后两元素是12,前面4个元素(4356)得到后,栈中元素剩12,且2在栈顶,不可能让栈底元素1在栈顶元素2之前出栈。不能得到154623的理由类似,当栈中元素只剩23,且3在栈顶,2不可能先于3出栈。得到325641的过程如下:1 2 3顺序入栈,32出栈,得到部分输出序列32;然后45入栈,5出栈,部分输出序列变为325;接着6入栈并退栈,部分输出序列变为3256;最后41退栈,得最终结果325641。 得到135426的过程如下:1入栈并出栈,得到部分输出序列1;然后2和3入栈,3出栈,部分输出序列变为13;接着4和5入栈,5,4和2依次出栈,部分输出序列变为13542;最后6入栈并退栈,得最终结果135426。3.3 若用一个大小为6的数组来实现循环队列,且当前rear和front的值分别为0和3,当从队列中删除一个元素,再加入两个元素后,rear和front的值分别为多少?【解答】2和 43.4 设栈S和队列Q的初始状态为空,元素e1,e2,e3,e4,e5和e6依次通过栈S,一个元素出栈后即进队列Q,若6个元素出队的序列是e3,e5,e4,e6,e2,e1,则栈S的容量至少应该是多少?【解答】 43.5 循环队列的优点是什么,如何判断“空”和“满”。【解答】循环队列解决了常规用0-m-1的数组表示队列时出现的“假溢出”(即队列未满但不能入队)。在循环队列中我们仍用队头指针等于队尾指针表示队空,而用牺牲一个单元的办法表示队满,即当队尾指针加1(求模)等于队头指针时,表示队列满。也有通过设标记以及用一个队头或队尾指针加上队中元素个数来区分队列的“空”和“满”的。3.6 设长度为n的链队列用单循环链表表示,若只设头指针,则入队和出队的时间如何?若只设尾指针呢?【解答】若只设头指针,则入队的时间为O(n),出队的时间为O(1)。若只设尾指针,则入队和出队的时间均为O(1)。3.7 指出下面程序段的功能是什么?(1) void demo1(SeqStack S)int i,arr64,n=0; while(!StackEmpty(S) arrn+=Pop(S); for(i=0;i1) printf(i-);【解答】void digui(int n)if(n1)printf(n); digui(n-1); 3.9 写出下列中缀表达式的后缀表达式: (1)A*B*C (2)(A+B)*C-D (3)A*B+C/(D-E) (4)(A+B)*D+E/(F+A*D)+C【解答】(1)ABC* (2)AB+C*D- (3)AB*CDE-/+ (4)AB+D*EFAD*+/+C+3.10 选择题:循环队列存储在数组A0.m中,则入队时的操作为( )。 A. rear=rear+1 B. rear=(rear+1) % (m-1)C. rear=(rear+1) % m D. rear=(rear+1) % (m+1)【解答】D3.11 选择题:4个园盘的Hahoi塔,总的移动次数为( )。A.7 B. 8 C.15 D.16【解答】C3.12选择题:允许对队列进行的操作有( )。 A. 对队列中的元素排序 B. 取出最近进队的元素C. 在队头元素之前插入元素 D. 删除队头元素【解答】D二、算法设计题3.13 利用栈的基本操作,编写求栈中元素个数的算法。【题目分析】 将栈值元素出栈,出栈时计数,直至栈空。【算法】 int StackLength(Stack S) /求栈中元素个数 int n=0; while(!StackEmpty(S) n+; Pop(S); return n; 算法讨论:若要求统计完元素个数后,不能破坏原来栈,则在计数时,将原栈导入另一临时栈,计数完毕,再将临时栈倒入原栈中。 int StackLength(Stack S) /求栈中元素个数 int n=0; Stack T;StackInit(T); /初始化临时栈T while(!StackEmpty(S) n+; Push(T,Pop(S); while(!StackEmpty(T) Push(S,Pop(T); return n; 3.14 双向栈S是在一个数组空间Vm内实现的两个栈,栈底分别处于数组空间的两端。试为此双向栈设计栈初始化Init(S)、入栈Push(S,i,x)、出栈Pop(S,i)算法,其中i为0或1,用以指示栈号。题目分析两栈共享向量空间,将两栈栈底设在向量两端,初始时,s1栈顶指针为-1,s2栈顶为m。两栈顶指针相邻时为栈满。两栈顶相向、迎面增长,栈顶指针指向栈顶元素。#define ElemType int 假设元素类型为整型typedef struct ElemType Vm; 栈空间 int top2; top为两个栈顶指针stk;stk S; S是如上定义的结构类型变量,为全局变量(1) 栈初始化int Init() S.top0=-1; S.top1=m; return 1; /初始化成功(2) 入栈操作:int push(stk S ,int i,int x)i为栈号,i=0表示左栈,i=1为右栈,x是入栈元素。入栈成功返回1,否则返回0if(i1)printf(“栈号输入不对n”);exit(0);if(S.top1-S.top0=1) printf(“栈已满n”);return(0);switch(i) case 0: S.V+S.top0=x; return(1); break;case 1: S.V-S.top1=x; return(1); push(3) 退栈操作 ElemType pop(stk S,int i) 退栈。i代表栈号,i=0时为左栈,i=1时为右栈。退栈成功返回退栈元素否则返回-1 if(i1)printf(“栈号输入错误n”);exit(0); switch(i) case 0: if(S.top0=-1) printf(“栈空n”);return(-1); else return(S.VS.top0-); case 1: if(S.top1=m printf(“栈空n”); return(-1); else return(S.VS.top1+); switch 算法结束(4) 判断栈空int Empty();return (S.top0=-1 & S.top1=m); 算法讨论 请注意算法中两栈入栈和退栈时的栈顶指针的计算。s1(左栈)是通常意义下的栈,而s2(右栈)入栈操作时,其栈顶指针左移(减1),退栈时,栈顶指针右移(加1)。 3.15设以数组Qm存放循环队列中的元素,同时设置一个标志tag,以tag=0和tag=1来区别在队头指针(front)和队尾指针(rear)相等时,队列状态为“空”还是“不空”。试编写相应的入队(QueueIn)和出队(QueueOut)算法。(1) 初始化SeQueue QueueInit(SeQueue Q) /初始化队列Q.front=Q.rear=0; Q.tag=0;return Q; (2) 入队SeQueue QueueIn(SeQueue Q,int e) /入队列if(Q.tag=1) & (Q.rear=Q.front) printf(队列已满n); else Q.rear=(Q.rear+1) % m;Q.dataQ.rear=e; if(Q.tag=0) Q.tag=1; /队列已不空return Q; (3)出队ElemType QueueOut(SeQueue Q)/出队列if(Q.tag=0) printf(队列为空n); elseQ.front=(Q.front+1) % m; e=Q.dataQ.front
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号