数据结构 第三章 栈和队列 作业(已批改)

判断题

1-1
若一个栈的输入序列为1,2,3,…,N,输出序列的第一个元素是 i,则第 j 个输出元素是 j−i−1。

T F

栈是一种先进后出的数据结构,也就是说如果入栈顺序为 123,那么出栈顺序则为 321。题目中栈的输入序列为 1,2,3,…,n,该序列是等差为 1 的递增序列,那么出栈顺序应该为 n,n-1…,3,2,1,也就是等差为 1 的递减序列。那么当输出序列的第一个元素为i时,利用等差数列公式 an = a1+(n-1)d 可知,第 j 个元素应为 aj = i+(j-1)(-1) = i-j+1。

在这里插入图片描述
1-2
Run the following operations on a stack S: Push(S,1), Push(S,2), Pop(S), Push(S,3), Pop(S), Pop(S). The output sequence must be {1, 2, 3}.

译文:在堆栈上运行以下操作:Push(S,1), Push(S,2), Pop(S), Push(S,3), Pop(S), Pop(S)。输出序列必须是{1,2,3}。

T F

{ 2, 3, 1}

1-3
Given the input sequence onto a stack as {1, 2, 3, …, N}. If the first output is i, then the j-th output must be j−i−1.

译文:给定堆栈上的输入序列为{1,2,3,…N}。如果第一个输出是i,那么第j个输出必须是j- i - 1。

T F

同 1-1

1-4
If keys are pushed onto a stack in the order {1, 2, 3, 4, 5}, then it is impossible to obtain the output sequence {3, 4, 1, 2, 5}.

译文:如果按{1,2,3,4,5}的顺序将键压入堆栈,则不可能获得输出序列{3,4,1,2,5}。

T F

1-5
若一个栈的输入序列为{1, 2, 3, 4, 5},则不可能得到{3, 4, 1, 2, 5}这样的出栈序列。

T F

同 1-4

1-7
If keys are pushed onto a stack in the order abcde, then it’s impossible to obtain the output sequence cdabe.

译文:如果按“abcde”顺序将键压入堆栈,则不可能获得输出序列“cdabe”。

T F

同 1-4

1-8
If keys are pushed onto a stack in the order abcde, then it’s impossible to obtain the output sequence cedab.

译文:如果按“abcde”顺序将键压入堆栈,则不可能获得输出序列“cedab”。

T F

cedba

1-9
Given that the pushing sequence of a stack is { 1, 2, ⋯, n } and popping sequence is { x​1​​ ,x​2​​ ,⋯,x​n​​ }. If x​2​​ =n, we can obtain n−1 different possible popping sequences.

译文:假设栈的push序列为{1,2,⋯⋯n}, pop序列为{x1, x2,⋯⋯x n}。如果x2 =n,我们可以得到n−1个不同的可能的取出序列。

T F

单选题

2-1
假设有5个整数以1、2、3、4、5的顺序被压入堆栈,且出栈顺序为3、5、4、2、1,那么为了获得这样的输出,堆栈大小至少为:

A:2
B:3
C:4
D:5

2-2
若元素a、b、c、d、e、f依次进栈,允许进栈、退栈操作交替进行,但不允许连续三次进行退栈工作,则不可能得到的出栈序列是?

A:b c a e f d
B:c b d a e f
C:d c e b f a
D:a f e d c b

f e d c 连续 4 次退栈;

2-3
设一个栈的输入序列是1、2、3、4、5,则下列序列中,是栈的合法输出序列的是?

A:3 2 1 5 4
B:5 1 2 3 4
C:4 5 1 3 2
D:4 3 1 2 5

2-4
令P代表入栈,O代表出栈。当利用堆栈求解后缀表达式1 2 3 + * 4 –时,堆栈操作序列是:

A:PPPOOPOO
B:PPOOPPOOPPOO
C:PPPOOPOOPPOO
D:PPPOOPOOPPOOPO

后缀表达式计算

为了解释后缀表达式的好处,我们先来看看,计算机如何应用后缀表达式计算出最终的结果20的。

后缀表达式:9 3 1 - 3 * + 10 2 / +

规则:从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。

下面是详细的步骤:

  1. 初始化一个空栈。此桟用来对要运算的数字进出使用。

  2. 后缀表达式中前三个都是数字,所以9、3、1进栈。
    在这里插入图片描述

  3. 接下来是减号“-”,所以将栈中的1出栈作为减数,3出栈作为被减数,并运算3-1得到2,再将2进栈。

  4. 接着是数字3进栈。
    在这里插入图片描述

  5. 后面是乘法“*”,也就意味着栈中3和2出栈,2与3相乘,得到6,并将6进栈。

  6. 下面是加法“+”,所以找中6和9出找,9与6相加,得到15,将15进栈。
    在这里插入图片描述

  7. 接着是10与2两数字进栈。

  8. 接下来是符号因此,栈顶的2与10出栈,10与2相除,得到5,将5进栈。
    在这里插入图片描述

  9. 最后一个是符号“+”,所以15与5出找并相加,得到20,将20进栈。

  10. 结果是20出栈,栈变为空。
    在这里插入图片描述

2-5
设一个堆栈的入栈顺序是1、2、3、4、5。若第一个出栈的元素是4,则最后一个出栈的元素必定是:

A:1
B:3
C:5
D:1或者5

2-6
从栈顶指针为ST的链栈中删除一个结点且用X保存被删结点的值,则执行:

A:X= ST->data;
B:X= ST; ST = ST->next;
C:X= ST->data; ST = ST->next;
D:ST = ST->next; X= ST->data;

课本P61

2-7
若采用带头、尾指针的单向链表表示一个堆栈,那么该堆栈的栈顶指针 top 应该如何设置?

A:将链表头设为 top
B:将链表尾设为 top
C:随便哪端作为 top 都可以
D:链表头、尾都不适合作为 top

课本P60:由于栈的主要操作是在栈顶插入和删除,显然以链表的头部作为栈顶是最方便的,而且没必要像单链表那样为了操作方便附加一个头结点;

2-8
若栈采用顺序存储方式存储,现两栈共享空间V[m]:top[i]代表第 i(i=1或2)个栈的栈顶;栈 1 的底在V[0],栈 2 的底在V[m-1],则栈满的条件是:

A:|top[2]-top[1]| == 0
B:top[1]+top[2] == m
C:top[1] == top[2]
D:top[1]+1 == top[2]

疑惑?

2-9
下列关于栈的叙述中,错误的是:

  1. 采用非递归方式重写递归程序时必须使用栈
  2. 函数调用时,系统要用栈保存必要的信息
  3. 只要确定了入栈次序,即可确定出栈次序
  4. 栈是一种受限的线性表,允许在其两端进行操作

A:仅 1
B:仅 1、2、3
C:仅 1、3、4
D:仅 2、3、4

  1. 计算斐波拉契数列迭代实现只需要一个循环即可实现。(疑惑??
  2. 肯定是错的,要不然前面那些选择题是啥
  3. 这种受限表现在:栈的插入和删除操作只允许在表的尾端进行(在栈中成为“栈顶”),满足“FIFO:First In Last Out”;队列只允许在表尾插入数据元素,在表头删除数据元素,满足“First In First Out”。
    课本P54:栈是限定仅在表尾(栈顶)进行插入或删除操作的线性表;

2-10
为解决计算机主机与打印机之间速度不匹配问题,通常设置一个打印数据缓冲区,主机将要输出的数据依次写入该缓冲区,而打印机则依次从该缓冲区中取出数据。该缓冲区的逻辑结构应该是?

A:堆栈
B:队列
C:树
D:图

2-11
若用大小为 6 的数组来实现循环队列,且当前 front 和 rear 的值分别为 0 和 4。当从队列中删除两个元素,再加入两个元素后,front 和 rear 的值分别为多少?

A:2和0
B:2和2
C:2和4
D:2和6

2-12
如果循环队列用大小为 m 的数组表示,队头位置为 front、队列元素个数为 size,那么队尾元素位置 rear 为:

A:front+size
B:front+size-1
C:(front+size)%m
D:(front+size-1)%m

2-13
循环顺序队列中是否可以插入下一个元素()。

A:与队头指针和队尾指针的值有关
B:只与队尾指针的值有关,与队头指针的值无关
C:只与数组大小有关,与队首指针和队尾指针的值无关
D:与曾经进行过多少次插入操作有关

课本P71:在循环队列中队空和队满的条件是:
队空的条件:Q.front == Q.rear
队满的条件:(Q.rear + 1) % MAXQSIZE == Q.front
(MAXQSIZE 为一开始 define 的队列可能达到的最大长度)

2-14
现有队列 Q 与栈 S,初始时 Q 中的元素依次是{ 1, 2, 3, 4, 5, 6 }(1在队头),S 为空。若允许下列3种操作:(1)出队并输出出队元素;(2)出队并将出队元素入栈;(3)出栈并输出出栈元素,则不能得到的输出序列是:

A:1, 2, 5, 6, 4, 3
B:2, 3, 4, 5, 6, 1
C:3, 4, 5, 6, 1, 2
D:6, 5, 4, 3, 2, 1

3, 4, 5, 6, 2, 1

编程题

7-1 符号配对 (20分)
请编写程序检查C语言源程序中下列符号是否配对://、(与)、[与]、{与}。

输入格式:
输入为一个C语言源程序。当读到某一行中只有一个句点.和一个回车的时候,标志着输入结束。程序中需要检查配对的符号不超过100个。

输出格式:
首先,如果所有符号配对正确,则在第一行中输出YES,否则输出NO。然后在第二行中指出第一个不配对的符号:如果缺少左符号,则输出?-右符号;如果缺少右符号,则输出左符号-?。

输入样例1:

void test()
{
    
    
    int i, A[10];
    for (i=0; i<10; i++) /*/
        A[i] = i;
}
.

输出样例1:

NO
/*-?

输入样例2:

void test()
{
    
    
    int i, A[10];
    for (i=0; i<10; i++) /**/
        A[i] = i;
}]
.

输出样例2:

NO
?-]

输入样例3:

void test()
{
    
    
    int i
    double A[10];
    for (i=0; i<10; i++) /**/
        A[i] = 0.1*i;
}
.

输出样例3:

YES
#include <bits/stdc++.h>
#include <stdio.h>
#define OK          1
#define ERROR       0
#define MAXSIZE 10000
using namespace std;

typedef char SElemType,Status;
const int MAXN=1e5+10;

//顺序栈的表示 
typedef struct{
    
    
	SElemType *base;
	SElemType *top;
	int stacksize;
}SqStack;

//顺序栈初始化
Status InitStack(SqStack &S) {
    
    
	S.base = new SElemType[MAXSIZE];
	if(!S.base)		return OVERFLOW;
	S.top = S.base;
	S.stacksize = MAXSIZE;
	return OK;
} 

//判断顺序栈是否为空
bool StackEmpty(SqStack S) {
    
    
	if(S.top == S.base) 	return true;
	else 	return false;
} 

//顺序栈进栈
/**
* (1)判断是否栈满,若满则出错
* (2)元素e压入栈顶
* (3)栈顶指针加1 
*/ 
Status Push(SqStack &S,SElemType e) {
    
    
	if(S.top - S.base == S.stacksize)	//栈满
		return ERROR;
	*S.top++ = e;
	return OK; 
}

//顺序栈出栈
/**
* (1)判断是否栈空,若空则出错 
* (2)获取栈顶元素e 
* (3)栈顶指针减1 
*/ 
Status Pop(SqStack &S,SElemType &e) {
    
    
	if(S.top == S.base)		//栈空
		return ERROR;
	--S.top;
  e = *S.top;
	return OK; 
}

//取顺序栈栈顶元素
/**
* (1)判断是否空栈,若空则返回错误 
* (2)否则通过栈顶指针获取栈顶元素 
*/ 
Status GetTop(SqStack S,SElemType &e) {
    
    
	if(S.top == S.base)		return ERROR;	//栈空
	e = *(S.top - 1);
	return OK; 
}

//取顺序栈栈底元素
Status GetBase(SqStack &S,SElemType &e) {
    
    
	if(S.base == S.top)		return ERROR;	//栈空
	e = *S.base;
	return OK;  
} 

int main(){
    
    
	char s[MAXN * 10], sign[MAXN], temp, ERRORKIND = ' ';
	int count = 0;
	SqStack S;
	InitStack(S);
	while(cin>>s && s[0] != '.') {
    
    
		int len = strlen(s);
		for(int i = 0; i < len; ++i) {
    
    
			if(s[i] == '(' || s[i] == ')' || s[i] == '[' || s[i] == ']' || s[i] == '{' || s[i] == '}') {
    
    
				sign[count++] = s[i]; 
			}else if(s[i] == '/' && s[i + 1] == '*') {
    
    
				sign[count++] = '/';
				++i;
			}else if(s[i] == '*' && s[i + 1] == '/') {
    
    
				sign[count++] = '*';
				++i;
			}
		}
	}
	for(int i = 0; i < count; ++i) {
    
    
		if(sign[i] == '(' || sign[i] == '[' || sign[i] == '{' || sign[i] == '/') {
    
    
			Push(S, sign[i]);
		}else if(sign[i] == ')'){
    
    
			if(GetTop(S,temp) && temp == '(') {
    
    
				Pop(S,temp);
			}else if(!GetTop(S,temp)) {
    
    
				ERRORKIND = ')';
				break; 
			}else {
    
    
				GetTop(S,temp);
				ERRORKIND = temp;
				break;
			}
		}else if(sign[i] == ']') {
    
    
			if(GetTop(S,temp) && temp == '[') {
    
    
				Pop(S,temp);
			}else if(!GetTop(S,temp)) {
    
    
				ERRORKIND = ']';
				break; 
			}else {
    
    
				GetTop(S,temp);
				ERRORKIND = temp;
				break;
			}
		}else if(sign[i] == '}') {
    
    
			if(GetTop(S,temp) && temp == '{') {
    
    
				Pop(S,temp);
			}else if(!GetTop(S,temp)) {
    
    
				ERRORKIND = '}';
				break; 
			}else {
    
    
				GetTop(S,temp);
				ERRORKIND = temp;
				break;
			}
		}else if(sign[i] == '*') {
    
    
			if(GetTop(S,temp) && temp == '/') {
    
    
				Pop(S,temp);
			}else if(!GetTop(S,temp)) {
    
    
				ERRORKIND = '*';
				break; 
			}else {
    
    
				GetTop(S,temp);
				ERRORKIND = temp;
				break;
			}
		}
	}
	if(ERRORKIND == ' ') {
    
    
		if(StackEmpty(S)) {
    
    	
			cout << "YES" << endl;
			return 0;
		}else {
    
    
			GetBase(S,ERRORKIND);
		}
	}
	cout << "NO" << endl;
	if(ERRORKIND == '(' || ERRORKIND == '[' || ERRORKIND == '{') {
    
    
		cout << ERRORKIND << "-?" << endl;
	}else if(ERRORKIND == ')' || ERRORKIND == ']' || ERRORKIND == '}') {
    
    
		cout << "?-" << ERRORKIND << endl;
	}else if(ERRORKIND == '/') {
    
    
		cout << "/*-?" << endl;
	}else if(ERRORKIND == '*') {
    
    
		cout << "?-*/" << endl;
	}
}

7-2 堆栈操作合法性 (20分)

假设以S和X分别表示入栈和出栈操作。如果根据一个仅由S和X构成的序列,对一个空堆栈进行操作,相应操作均可行(如没有出现删除时栈空)且最后状态也是栈空,则称该序列是合法的堆栈操作序列。请编写程序,输入S和X序列,判断该序列是否合法。

输入格式:
输入第一行给出两个正整数N和M,其中N是待测序列的个数,M(≤50)是堆栈的最大容量。随后N行,每行中给出一个仅由S和X构成的序列。序列保证不为空,且长度不超过100。

输出格式:
对每个序列,在一行中输出YES如果该序列是合法的堆栈操作序列,或NO如果不是。

输入样例:

4 10
SSSXXSXXSX
SSSXXSXXS
SSSSSSSSSSXSSXXXXXXXXXXX
SSSXXSXXX

输出样例:

YES
NO
NO
NO

猜你喜欢

转载自blog.csdn.net/Jessieeeeeee/article/details/105751002
今日推荐