第三章栈和队列习题_数据结构

第三章栈和队列习题_数据结构
第三章栈和队列习题_数据结构

习题三 栈和队列

单项选择题

1. 在作进栈运算时 , 应先判别栈是否 (① 当栈中元素为 n 个 ,作进栈运算时发生上溢①, ②: A. 空 B. 满 C.

③: A. n-1 B. n C. n+1 D

2.若已知一个栈的进栈序列是 1, 2, 3, ?, p1= 3,则 p2 为( ) 。

A 可能是 2

B 一 定是 2 C

3. 有六个元素 6,5,4, 3, 2,1 的顺序进栈, 上溢 D. 下溢 n/2 n ,其输出序列为 p1, p2, p3, ... ,pn ,若 可能是 1 D 一定是 1 问下列哪一个不是合法的出栈序列( )

A. 3,2,4,1,1 ;(*^(+*-

B. 3,2,8

C. 3,2,4,2,2 ;(*^(-

D. 3,2,8

8. 用链接方式存储的队列,在进行删除运算时( )。

9. 递归过程或函数调用时,处理参数及返回地址,要用一种称为( )的数据结构。 A .队列

B .多维数组

C .栈 D. 线性表

10.设 C 语言数组 Data[m+1] 作为循环队列 SQ 的存储空间, front 为队头指针, rear 为队 尾

指针,则执行出队操作的语句为 ( )

=(rear+1)%(m+1) D. front=(front+1)%(m+1) 11. 循环队列的队满条件为 ( )

A. +1) % maxsize ==+1) % maxsize;

B. +1) % maxsize ==

C. +1) % maxsize == 12. 栈和队列的共同点是(

)。

A. 5 4 3 6 1 2

B. 4 5 3 1 2 6

C. 3 4 6 5 2 1

D. 2 3 4 1 5 6

4.设有一顺序栈 S ,元素 s 1,s 2,s 3,s 4,s 5,s 6依次进栈,如果 6个元素出栈的顺序是 s 2,s 3,s 4, s 6,

s 5,s 1, 则栈的容量至少应该是

( ) B. 3 C. 5 5. 若栈采用顺序存储方式存储,现两栈共享空间 V[1..m] , top[i] 代表第 i 个栈 ( i =1,2) 栈顶,栈 1的底在 v[1] ,栈 2的底在 V[m] ,则栈满的条件是( )。 A. |top[2]-top[1]|=0 C. top[1]+top[2]=m 6. 执行完下列语句段后, B. top[1]+1=top[2] D. top[1]=top[2] i 值为:( ) int f(int x)

{ return ((x>0) x* f(x-1):2);} int i ;

i =f(f(1)); A .2 B. 4 C. 8 D. 无限递归

7. 表达式 3* 2^(4+2*2-6*3)-5 ^

为乘幂 。

求值过程中当扫描

6 时,对象栈和算符栈为

( ),其中

A. 仅修改头指针

B. 仅修改尾指针

C. 头、尾指针都要修改

D. 头、尾指针可能都要修改

), 在作退栈运算时应先判别栈是

否 , 则说明该栈的最大容量为

;(*^(-

=front+1 B. front=

front+1 ) % m

A. 都是先进先出

B.都是先进后出

C. 只允许在端点处插入和删除元素

D. 没有共同点

二、填空题

1.栈是_____ 的线性

表,其运算遵循_____ 的原则。

2. 一个栈的输入序列是:1,2,3 则不可能的栈输出序列是_______ 。

3.用S 表示入栈操作,X 表示出栈操作,若元素入栈的顺序为1234,为了得到1342 出栈顺序,相应的S 和X 的操作串为_____ 。

4. 循环队列的引入,目的是为了克服 _______ 。

5.队列是限制插入只能在表的一端,而删除在表的另一端进行的线性表,其特点是______

6. 已知链队列的头尾指针分别是 f 和r ,则将值x 入队的操作序列是 _________ 。

7.表达式求值是 _____ 应用的一个典型例子。

8.循环队列用数组A[0..m-1] 存放其元素值,已知其头尾指针分别是front 和rear ,则当前队列的元素个数是 __________ 。

9. 以下运算实现在链栈上的初始化,请在 _________________ 处用请适当句子予以填充。

Void InitStacl(LstackTp *ls){ ______________ ;}

10. `以下运算实现在链栈上的进栈,请在处用请适当句子予以填充。

Void Push ( LStackTp *ls,DataType x )

{ LstackTp *p;p=malloc(sizeof(LstackTp));

p->next=ls;

}

11.以下运算实现在链栈上的退栈,请在 _________________ 处用请适当句子予以填充。

Int Pop(LstackTp *ls,DataType *x)

{LstackTp *p; if(ls!=NULL)

{ p=ls;

ls=ls->next;

return(1)

}else return(0);

12. 以下运算实现在链队上的入队列,请在 _________________ 处用适当句子予以填充。

Void EnQueue(QueptrTp *lq,DataType x)

}

{ LqueueTp *p; p=(LqueueTp *)malloc(sizeof(LqueueTp));

______________ =x;

p->next=NULL;

(lq->rear)->next= _______________

三、应用题1.给出栈的两种存储结构形式名称,在这两种栈的存储结构中如何判别栈空与栈满

2. 画出对算术表达式A-B*C/D-E ↑F 求值时操作数栈和运算符栈的变化过程。

3. 将两个栈存入数组V[1..m] 应如何安排最好这时栈空、栈满的条件是什么

4. 怎样判定循环队列的空和满

四、算法设计题

1.借助栈(可用栈的基本运算)来实现单链表的逆置运算。

2. 设表达式以字符形式已存入数组E[n] 中,‘ #'为表达式的结束符,试写出判断表达式中

括号(‘('和‘)')是否配对的C语言描述算法:EXYX(E); (注:算法中可调用栈操作的基本算法。)

3. 假设以I 和O 分别表示入栈和出栈操作。栈的初态和终态均为空,入栈和出栈的操作序列可表示为仅由I 和O组成的序列,称可以操作的序列为合法序列,否则称为非法序列。

(1)下面所示的序列中哪些是合法的

A. IOIIOIOO

B. IOOIOIIO

C. IIIOIOIO

D. IIIOOIOO

(2)通过对(1)的分析,写出一个算法,判定所给的操作序列是否合法。若合法,返回true ,否则返回false (假定被判定的操作序列已存入一维数组中)。

4. 设有两个栈S1,S 2 都采用顺序栈方式,并且共享一个存储区[O..maxsize-1], 为了尽量利

用空间,减少溢出的可能,可采用栈顶相向,迎面增长的存储方式。试设计S1,S 2有关入栈和出栈的操作算法。

5. 请利用两个栈S1和S2来模拟一个队列。已知栈的三个运算定义如下:PUSH(ST,x): 元素x入ST栈;POP(ST,x):ST栈顶元素出栈,赋给变量x;Sempty(ST):判ST栈是否为空。那么如何利用栈的运算来实现该队列的三个运算:enqueue: 插入一个元素入队列;dequeue: 删除一个元素出队列;queue_empty :判队列为空。(请写明算法的思想及必要的注释)

6.要求循环队列不损失一个空间全部都能得到利用,设置一个标志tag, 以tag 为0 或1来区分头尾指针相同时的队列状态的空与满,请编写与此相应的入队与出队算法。

7. 已知Q是一个非空队列,S 是一个空栈。仅用队列和栈的ADT函数和少量工作变量,编写一个算法,将队列Q中的所有元素逆置。栈的ADT函数有:

makeEmpty(s:stack);

push(s:stack;value:datatype);

pop(s:stack):datatype;

isEmpty(s:stack):Boolean; 队列的ADT 函数有:置空栈

新元素value 进栈出栈,返回栈顶值判栈空否

enqueue(q:queue:value:datatype);

deQueue(q:queue):datatype; isEmpty(q:queue):boolean;元素value 进队出队列,返回队头值判队列空否

第 3 章栈和队列

一单项选择题

1. B A B

2. A

3. C

5. B

6. B

7. D

8. D

9. C

10.D

12. C

二、填空题

1.操作受限(或限定仅在表尾进行插入和删除操作) 后进先出

2. 3 1 2

3.S× SS×S××

4. 假溢出时大量移动数据元素

5.先进先出

6. s=(LinkedList)malloc( sizeof (LNode)) ;s->data=x;s->next=r->next ;r->next=s ;

r=s ;

7.栈

8.( rear-front+m ) % m;

9.ls=NULL

10.p->data=x, ls=p

11.p->data, free(p)

12.p->data, p, lq->rear=p

三、应用题

1.【解答】( 1)顺序栈 (top 用来存放栈顶元素的下标)

判断栈S 空:如果S->top==-1 表示栈空。

判断栈S 满:如果S->top==Stack_Size-1 表示栈满。

(2) 链栈( top 为栈顶指针,指向当前栈顶元素前面的头结点) 判断栈空:如果

top->next==NULL 表示栈空。判断栈满:当系统没有可用空间时,申请不到空间存放

要进栈的元素,此时栈满。

3. 设栈S1 和栈S2 共享向量V[1..m] ,初始时,栈S1 的栈顶指针top[0]=0 ,栈S2 的栈顶

指针top[1]=m+1 ,当top[0]=0 为左栈空,top[1]=m+1 为右栈空;当top[0]=0 并且top[1]=m+1 时为全栈空。当top[1]-top[0]=1 时为栈满。

4. 设顺序存储队列用一维数组q[m] 表示,其中m为队列中元素个数,队列中元素在向量中的下标从0 到m-1。设队头指针为front ,队尾指针是rear ,约定front 指向队头元素的前一位置,rear 指向队尾元素。当front 等于-1 时队空,rear 等于m-1 时为队满。由于队列的性质(“删除”在队头而“插入”在队尾),所以当队尾指针rear 等于m-1 时,若front 不等于-1 ,则队列中仍有空闲单元,所以队列并不是真满。这时若再有入队操作,会造成假“溢出”。其解决办法有二,一是将队列元素向前“平移” (占用0 至rear-front-1 );二是将队列看成首尾相连,即循环队列(0..m-1 )。在循环队列下,仍定义front=rear 时为队空,而判断队满则用两种办法,一是用“牺牲一个单元” ,即rear+1=front (准确记是

(rear+1 )%m=front ,m是队列容量)时为队满。另一种解法是“设标记”方法,如设标记tag ,tag 等于0 情况下,若删除时导致front=rear 为队空;tag=1 情况下,若因插入导致front=rear 则为队满。

四算法设计题

1.解:方法是先依次让单链表上的元素进栈,然后再依次出栈。

Void invert (lklist head)

{LstackTp s;

initstack(s);

p= head;

while (p<>null)

{Push (s,p->data);p=p->next;}

p=head;

while(not emptystack(s))

{pop(s,p->data); p=p->next;}

}

2. [ 题目分析]判断表达式中括号是否匹配,可通过栈,简单说是左括号时进栈,右括号时退栈。退栈时,若栈顶元素是左括号,则新读入的右括号与栈顶左括号就可消去。如此下去,输入表达式结束时,栈为空则正确,否则括号不匹配。

int EXYX(char E[], int n)

( 1)A和D是合法序列, B 和 C 是非法序列。

( 2)设被判定的操作序列已存入一维数组A中。

int Judge( char A[])

0'0'[ 题目分析] 栈的特点是后进先出,队列的特点是先进先出。所以,用两个栈s1 和s2 模拟一个队列时,s1 作输入栈,逐个元素压栈,以此模拟队列元素的入队。当需要出队时,将栈s1 退栈并逐个压入栈s2 中,s1 中最先入栈的元素,在s2 中处于栈顶。s2 退栈,相当于队列的出队,实现了先进先出。显然,只有栈s2为空且s1 也为空,才算是队列空。

(1) int enqueue(stack s1,elemtp x)

[ 题目分析] 根据队列先进先出和栈后进先出的性质,先将非空队列中的元素出队,并压入初始为空的栈中。这时栈顶元素是队列中最后出队的元素。然后将栈中元素出栈,依次插入到初始为空的队列中。栈中第一个退栈的元素成为队列中第一个元素,最后退栈的元素 (出队时第一个元素)成了最后入队的元素,从而实现了原队列的逆置。

void Invert(queue Q)

//Q 是一个非空队列,本算法利用空栈S 和已给的几个栈和队列的ADT函数,将队列Q中的元素逆置。

{makempty(S); // 置空栈

while (!isEmpty(Q)) // 队列Q中元素出队

{value=deQueue(Q); push(S,value); }// 将出队元素压入栈中

while (!isEmpty(S)) // 栈中元素退栈

{value=pop(S); enQueue(Q,value); }// 将出栈元素入队列Q

}// 算法invert 结束

相关主题
相关文档
最新文档