1-1
所谓“循环队列”是指用单向循环链表或者循环数组表示的队列。
F
1-2
在用数组表示的循环队列中,front值一定小于等于rear值。
F
1-3
不论是入队列操作还是入栈操作,在顺序存储结构上都需要考虑"溢出"情况。
T
1-4
可以通过少用一个存储空间的方法解决循环队列假溢出现象。
F
真溢出:Q.rear==Q.front;
假性溢出:当队列中的存储空间没满时,但是由于来的元素堵在队尾,此时如果还有元素要入队的话,就会报错,发生溢出;
为了解决这个问题,有如下方法:
-
按最大可能的进队操作次数设置顺序队列的最多元素个数,比如说如果要操作16次,则可以存储8个元素;但是这个方法很浪费空间,一般不用这个方法;
-
修改出队操作算法,使每次出队后都把队列中剩余的操作元素向队头移动一个位置;
-
修改入队算法,增加判断条件,当发生“假性溢出”时,把数据元素向队头移动;
-
采用循环队列;
循环队列中当rear==front时,有可能是队满,也有可能是队空,为了判断属于哪种,有如下方法;
-
方法一:加设标志位
-
判队满:
-
tag =1 && Q.rear == Q.front;
-
-
判队空:
-
tag =0 && Q.rear== Q.front;
-
方法二:少用一个存储单元
-
判队满:
-
Q.front = (Q.rear+1)%MAXSIZE;
-
判队空:
-
Q.front == Q.rear;
-
-
1-5
队列适合解决处理顺序与输入顺序相反的问题。
F
2-1
为解决计算机主机与打印机之间速度不匹配问题,通常设置一个打印数据缓冲区,主机将要输出的数据依次写入该缓冲区,而打印机则依次从该缓冲区中取出数据。该缓冲区的逻辑结构应该是?
A.堆栈
B.队列
C.树
D.图
2-2
若已知一队列用单向链表表示,该单向链表的当前状态(含3个对象)是:1->2->3
,其中x->y
表示x
的下一节点是y
。此时,如果将对象4
入队,然后队列头的对象出队,则单向链表的状态是:
A.1->2->3
B.2->3->4
C.4->1->2
D.答案不唯一
2-3
若用大小为6的数组来实现循环队列,且当前front
和rear
的值分别为0和4。当从队列中删除两个元素,再加入两个元素后,front
和rear
的值分别为多少?
A.2和0
B.2和2
C.2和4
D.2和6
2-4
如果循环队列用大小为m
的数组表示,且用队头指针front
和队列元素个数size
代替一般循环队列中的front
和rear
指针来表示队列的范围,那么这样的循环队列可以容纳的元素个数最多为:
A.m-1
B.m
C.m+1
D.不能确定
2-5
循环顺序队列中是否可以插入下一个元素()。
A.与队头指针和队尾指针的值有关
B.只与队尾指针的值有关,与队头指针的值无关
C.只与数组大小有关,与队首指针和队尾指针的值无关
D.与曾经进行过多少次插入操作有关
2-6
最不适合用作链队的链表是()。
A.只带队头指针的非循环双链表
B.只带队头指针的循环双链表
C.只带队尾指针的循环双链表
D.只带队尾指针的循环单链表
2-7
现有队列 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
2-8
循环队列的引入,目的是为了克服( )。
A.假溢出问题
B.真溢出问题
C.空间不够用
D.操作不方便
2-9
已知初始为空的队列 Q 的一端仅能进行入队操作,另外一端既能进行入队操作又能进行出队操作。若 Q 的入队序列是 1、2、3、4、5,则不能得到的出队序列是:
A.5、4、3、1、2
B.5、3、1、2、4
C.4、2、1、3、5
D.4、1、3、2、5
2-10
线性表、堆栈、队列的主要区别是什么?
A.线性表用指针,堆栈和队列用数组
B.堆栈和队列都是插入、删除受到约束的线性表
C.线性表和队列都可以用循环链表实现,但堆栈不能
D.堆栈和队列都不是线性结构,而线性表是
6-1 另类循环队列
如果用一个循环数组表示队列,并且只设队列头指针Front,不设尾指针Rear,而是另设Count记录队列中元素个数。请编写算法实现队列的入队和出队操作。
函数接口定义:
bool AddQ( Queue Q, ElementType X ); ElementType DeleteQ( Queue Q );
其中Queue
结构定义如下:
typedef int Position;
typedef struct QNode *PtrToQNode;
struct QNode {
ElementType *Data; /* 存储元素的数组 */
Position Front; /* 队列的头指针 */
int Count; /* 队列中元素个数 */
int MaxSize; /* 队列最大容量 */
};
typedef PtrToQNode Queue;
注意:如果队列已满,AddQ
函数必须输出“Queue Full”并且返回false;如果队列是空的,则DeleteQ
函数必须输出“Queue Empty”,并且返回ERROR。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
#define ERROR -1
typedef int ElementType;
typedef enum { addq, delq, end } Operation;
typedef enum { false, true } bool;
typedef int Position;
typedef struct QNode *PtrToQNode;
struct QNode {
ElementType *Data; /* 存储元素的数组 */
Position Front; /* 队列的头、尾指针 */
int Count; /* 队列中元素个数 */
int MaxSize; /* 队列最大容量 */
};
typedef PtrToQNode Queue;
Queue CreateQueue( int MaxSize )
{
Queue Q = (Queue)malloc(sizeof(struct QNode));
Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
Q->Front = 0;
Q->Count = 0;
Q->MaxSize = MaxSize;
return Q;
}
bool AddQ( Queue Q, ElementType X );
ElementType DeleteQ( Queue Q );
Operation GetOp(); /* 裁判实现,细节不表 */
int main()
{
ElementType X;
Queue Q;
int N, done = 0;
scanf("%d", &N);
Q = CreateQueue(N);
while ( !done ) {
switch( GetOp() ) {
case addq:
scanf("%d", &X);
AddQ(Q, X);
break;
case delq:
X = DeleteQ(Q);
if ( X!=ERROR ) printf("%d is out\n", X);
break;
case end:
while (Q->Count) printf("%d ", DeleteQ(Q));
done = 1;
break;
}
}
return 0;
}
/* 你的代码将被嵌在这里 */
bool AddQ(Queue Q, ElementType X)
{
if(Q->Count == Q->MaxSize)//是否满
{
printf("Queue Full\n");
return false;
}
Q->Count++;
Q->Data[(Q->Front + Q->Count) % Q->MaxSize] = X;
return true;
}
ElementType DeleteQ(Queue Q)
{
if(Q->Count == 0)//是否空
{
printf("Queue Empty\n");
return ERROR;
}
Q->Count--;
Q->Front = (Q->Front+1) % Q->MaxSize;
return Q->Data[Q->Front];
}
6-2 双端队列
双端队列(deque,即double-ended queue的缩写)是一种具有队列和栈性质的数据结构,即可以(也只能)在线性表的两端进行插入和删除。若以顺序存储方式实现双端队列,请编写例程实现下列操作:
Push(X,D)
:将元素X
插入到双端队列D
的头;Pop(D)
:删除双端队列D
的头元素,并返回;Inject(X,D)
:将元素X
插入到双端队列D
的尾部;Eject(D)
:删除双端队列D
的尾部元素,并返回。
函数接口定义:
typedef int Position;
typedef struct QNode *PtrToQNode;
struct QNode {
ElementType *Data; /* 存储元素的数组 */
Position Front, Rear; /* 队列的头、尾指针 */
int MaxSize; /* 队列最大容量 */
};
typedef PtrToQNode Deque;
其中Deque
结构定义如下:
typedef int Position;
typedef struct QNode *PtrToQNode;
struct QNode {
ElementType *Data; /* 存储元素的数组 */
Position Front, Rear; /* 队列的头、尾指针 */
int MaxSize; /* 队列最大容量 */
};
typedef PtrToQNode Deque;
注意:Push
和Inject
应该在正常执行完操作后返回true,或者在出现非正常情况时返回false。当Front
和Rear
相等时队列为空,Pop
和Eject
必须返回由裁判程序定义的ERROR
。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
#define ERROR -1
typedef int ElementType;
typedef enum { push, pop, inject, eject, end } Operation;
typedef enum { false, true } bool;
typedef int Position;
typedef struct QNode *PtrToQNode;
struct QNode {
ElementType *Data; /* 存储元素的数组 */
Position Front, Rear; /* 队列的头、尾指针 */
int MaxSize; /* 队列最大容量 */
};
typedef PtrToQNode Deque;
Deque CreateDeque( int MaxSize )
{ /* 注意:为区分空队列和满队列,需要多开辟一个空间 */
Deque D = (Deque)malloc(sizeof(struct QNode));
MaxSize++;
D->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
D->Front = D->Rear = 0;
D->MaxSize = MaxSize;
return D;
}
bool Push( ElementType X, Deque D );
ElementType Pop( Deque D );
bool Inject( ElementType X, Deque D );
ElementType Eject( Deque D );
Operation GetOp(); /* 裁判实现,细节不表 */
void PrintDeque( Deque D ); /* 裁判实现,细节不表 */
int main()
{
ElementType X;
Deque D;
int N, done = 0;
scanf("%d", &N);
D = CreateDeque(N);
while (!done) {
switch(GetOp()) {
case push:
scanf("%d", &X);
if (!Push(X, D)) printf("Deque is Full!\n");
break;
case pop:
X = Pop(D);
if ( X==ERROR ) printf("Deque is Empty!\n");
else printf("%d is out\n", X);
break;
case inject:
scanf("%d", &X);
if (!Inject(X, D)) printf("Deque is Full!\n");
break;
case eject:
X = Eject(D);
if ( X==ERROR ) printf("Deque is Empty!\n");
else printf("%d is out\n", X);
break;
case end:
PrintDeque(D);
done = 1;
break;
}
}
return 0;
}
/* 你的代码将被嵌在这里 */
bool Push(ElementType X, Deque D)
{
if ((D->Front - D->Rear + D->MaxSize) % D->MaxSize == 1)//是否满
{
return false;
}
D->Front = (D->Front - 1 + D->MaxSize) % D->MaxSize;//后退
D->Data[D->Front] = X;
return true;
}
ElementType Pop(Deque D)
{
if (D->Front == D->Rear)
{
return ERROR;
}
int num = D->Data[D->Front];
D->Front = (D->Front + 1) % D->MaxSize;//前进
return num;
}
bool Inject( ElementType X, Deque D )
{
if ((D->Front - D->Rear + D->MaxSize) % D->MaxSize == 1)
{
return false;
}
D->Data[D->Rear] = X;
D->Rear = (D->Rear + 1) % D->MaxSize;//前进
return true;
}
ElementType Eject( Deque D )
{
if (D->Front == D->Rear)
{
return ERROR;
}
int num = D->Data[(D->Rear - 1 + D->MaxSize) % D->MaxSize];//后退
D->Rear = (D->Rear - 1 + D->MaxSize) % D->MaxSize;
return num;
}
#include <iostream>
#include <set>
using namespace std;
int main()
{
int n,m;
cin>>n;
set<int> st;
for(int i=0;i<n;i++)
{
cin>>m;
if(st.upper_bound(m)!=st.end())
{
st.erase(st.upper_bound(m));
}
st.insert(m);
}
cout<<st.size()<<endl;
return 0;
}