DS_Queue

1-1

所谓“循环队列”是指用单向循环链表或者循环数组表示的队列。

F


1-2

在用数组表示的循环队列中,front值一定小于等于rear值。

F


1-3

不论是入队列操作还是入栈操作,在顺序存储结构上都需要考虑"溢出"情况。

T


1-4

可以通过少用一个存储空间的方法解决循环队列假溢出现象。

F

真溢出:Q.rear==Q.front;

假性溢出:当队列中的存储空间没满时,但是由于来的元素堵在队尾,此时如果还有元素要入队的话,就会报错,发生溢出;

为了解决这个问题,有如下方法:

  1. 按最大可能的进队操作次数设置顺序队列的最多元素个数,比如说如果要操作16次,则可以存储8个元素;但是这个方法很浪费空间,一般不用这个方法;

  2. 修改出队操作算法,使每次出队后都把队列中剩余的操作元素向队头移动一个位置;

  3. 修改入队算法,增加判断条件,当发生“假性溢出”时,把数据元素向队头移动;

  4. 采用循环队列;

 

 

循环队列中当rear==front时,有可能是队满,也有可能是队空,为了判断属于哪种,有如下方法;

  • 方法一:加设标志位

    1.   判队满:

    2.   tag =1 && Q.rear == Q.front;

  • 判队空:
  • tag =0 && Q.rear== Q.front;
  •  方法二:少用一个存储单元

    1. 判队满:

    2. Q.front = (Q.rear+1)%MAXSIZE;

      1. 判队空:

      2. 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的数组来实现循环队列,且当前frontrear的值分别为0和4。当从队列中删除两个元素,再加入两个元素后,frontrear的值分别为多少?

A.2和0

B.2和2

C.2和4

D.2和6


2-4

如果循环队列用大小为m的数组表示,且用队头指针front和队列元素个数size代替一般循环队列中的frontrear指针来表示队列的范围,那么这样的循环队列可以容纳的元素个数最多为:

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; 

注意:PushInject应该在正常执行完操作后返回true,或者在出现非正常情况时返回false。当FrontRear相等时队列为空,PopEject必须返回由裁判程序定义的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;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

102101222_张凯权

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值