数据结构——循环队列PTA习题

简介: 数据结构——循环队列PTA习题

单选题



题解


初始化创建空队列时,令front=rear=0,每当插入新的队列尾元素时,rear增1,每当删除一个队列首元素时,front增1。因此,在非空队列中,头指针始终指向队列头元素,而尾指针始终指向队列尾元素的下一个位置。


front :0+2=2,


rear 4+2=6——>0.


函数题


6-1 另类循环队列 (20分)


如果用一个循环数组表示队列,并且只设队列头指针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。


输入样例:


4
Del
Add 5
Add 4
Add 3
Del
Del
Add 2
Add 1
Add 0
Add 10
End


输出样例:


Queue Empty
5 is out
4 is out
Queue Full
3 2 1 0


代码


#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->MaxSize==Q->Count)
  {
    printf("Queue Full\n");
    return ERROR;
  }
  ++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 双端队列 (25分)


双端队列(deque,即double-ended queue的缩写)是一种具有队列和栈性质的数据结构,即可以(也只能)在线性表的两端进行插入和删除。若以顺序存储方式实现双端队列,请编写例程实现下列操作:


Push(X,D):将元素X插入到双端队列D的头;


Pop(D):删除双端队列D的头元素,并返回;


Inject(X,D):将元素X插入到双端队列D的尾部;


Eject(D):删除双端队列D的尾部元素,并返回。


函数接口定义:


bool Push( ElementType X, Deque D );
ElementType Pop( Deque D );
bool Inject( ElementType X, Deque D );
ElementType Eject( Deque D );


其中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。


输入样例:


3
Pop
Inject 1
Pop
Eject
Push 2
Push 3
Eject
Inject 4
Inject 5
Inject 6
Push 7
Pop
End


输出样例:


Deque is Empty!
1 is out
Deque is Empty!
2 is out
Deque is Full!
Deque is Full!
3 is out
Inside Deque: 4 5


代码


#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)
{
  // 算尾部位置,如果满了返回false
  if ((D->Rear + 1) % (D->MaxSize) == D->Front)
    return false;
  // 减完了才能用公式
  D->Front--;
  D->Front = (D->MaxSize + D->Front) % (D->MaxSize);
  D->Data[D->Front] = X;
  return true;
}
// 头删
ElementType Pop(Deque D)
{
  if (D->Front == D->Rear)
    return ERROR;
  ElementType d = D->Data[D->Front];
  D->Front++;
  D->Front = D->Front % (D->MaxSize);
  return d;
}
// 尾插
bool Inject(ElementType X, Deque D)
{
    // 算尾部位置,如果满了返回false
  if ((D->Rear + 1) % (D->MaxSize) == D->Front)
    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;
  if (!D->Rear)
    D->Rear = D->MaxSize;
  D->Rear--;
  ElementType d = D->Data[D->Rear];
  return d;
}


编程题


7-1 堆栈模拟队列 (25分)


设已知有两个堆栈S1和S2,请用这两个堆栈模拟出一个队列Q。


所谓用堆栈模拟队列,实际上就是通过调用堆栈的下列操作函数:


int IsFull(Stack S):判断堆栈S是否已满,返回1或0;


int IsEmpty (Stack S ):判断堆栈S是否为空,返回1或0;


void Push(Stack S, ElementType item ):将元素item压入堆栈S;


ElementType Pop(Stack S ):删除并返回S的栈顶元素。


实现队列的操作,即入队void AddQ(ElementType item)和出队ElementType DeleteQ()。


输入格式:


输入首先给出两个正整数N1和N2,表示堆栈S1和S2的最大容量。随后给出一系列的队列操作:A item表示将item入列(这里假设item为整型数字);D表示出队操作;T表示输入结束。


输出格式:


对输入中的每个D操作,输出相应出队的数字,或者错误信息ERROR:Empty。如果入队操作无法执行,也需要输出ERROR:Full。每个输出占1行。


输入样例:


3 2
A 1 A 2 A 3 A 4 A 5 D A 6 D A 7 D A 8 D D D D T


输出样例:


ERROR:Full
1
ERROR:Full
2
3
4
7
8
ERROR:Empty


代码


模拟队列


#include<stdio.h>
#include<iostream>
#include<stack>
#include<string>
using namespace std;
stack<int>s1, s2;   //定义两个栈
int n1, n2;         //两个栈的容量
int main()
{
  char c;
  int m, p, q;
  cin >> n1 >> n2;
  if (n1 > n2) 
    swap(n1, n2);  // 保证更大的容量的S2作为输出栈
  getchar();
  while (1) 
  {     
    // 无限循环输入
    cin >> c;
    if (c == 'T') 
      break;     // 输入字符为T时结束
    if (c == 'A') 
    {
      cin >> m;
      if (s1.size() == n1 && s2.size() != 0)   // 只有当s1为满,s2不为空时才是满的情况
        printf("ERROR:Full\n");
      else if (s1.size() == n1 && s2.size() == 0) 
      {   
        // 当s1为满,s2为空时,先将s1里面所有的元素转移到s2,再将新加入的元素放置s1
        q = n1;
        while (q--) 
        {
          p = s1.top();
          s1.pop();
          s2.push(p);
        }
        s1.push(m);
      }
      else if (s1.size() != n1)  // 若s1不满,可直接将新入的元素放置s1里面
        s1.push(m);;
    }
    if (c == 'D') 
    {   
      //输入字符为D时要出队
      if (s1.size() == 0 && s2.size() == 0)    //只有当s1,s2均为空时才为队空的情况
        printf("ERROR:Empty\n");
      else if (s1.size() != 0 && s2.size() == 0)
      {  
        //若s2为空,s1不空,则先把s1里面所有元素转移至s2,再输出s2的栈顶元素
        q = s1.size();
        while (q--) {
          p = s1.top();
          s1.pop();
          s2.push(p);
        }
        cout << s2.top() << endl;
        s2.pop();
      }
      else if (s2.size() != 0) 
      { 
        //如果s2不为空,可直接输出s2栈顶元素
        cout << s2.top() << endl;
        s2.pop();
      }
    }
  }
  return 0;
}


直接用queue


#include<bits/stdc++.h> 
using namespace std;
queue<int> q; 
int main()
{  
    int m,n,i,a;  
    char c;  
    cin>>m>>n;  
    n+=m; 
    for(i=0;;i++)
  {  
        cin>>c;  
        if(c=='T')  
            return 0;
        if(c=='A')
    {  
            cin>>a;  
            if(q.size()==n)
      {
                cout<<"ERROR:Full"<<endl;  
            }  
            else
      {  
                q.push(a);  
            }  
        }  
        else if(c=='D')
    {  
            if(q.size()==0)
      {  
                cout<<"ERROR:Empty"<<endl;  
            }  
            else
      {  
                cout<<q.front()<<endl;  
                q.pop();   
            }  
        }  
    }  
    return 0;  
}
相关文章
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
857 77
|
存储 C++
【C++数据结构——树】哈夫曼树(头歌实践教学平台习题) 【合集】
【数据结构——树】哈夫曼树(头歌实践教学平台习题)【合集】目录 任务描述 相关知识 测试说明 我的通关代码: 测试结果:任务描述 本关任务:编写一个程序构建哈夫曼树和生成哈夫曼编码。 相关知识 为了完成本关任务,你需要掌握: 1.如何构建哈夫曼树, 2.如何生成哈夫曼编码。 测试说明 平台会对你编写的代码进行测试: 测试输入: 1192677541518462450242195190181174157138124123 (用户分别输入所列单词的频度) 预
538 14
【C++数据结构——树】哈夫曼树(头歌实践教学平台习题) 【合集】
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
518 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
算法 C++
【C++数据结构——查找】二叉排序树(头歌实践教学平台习题)【合集】
【数据结构——查找】二叉排序树(头歌实践教学平台习题)【合集】 目录 任务描述 相关知识 测试说明 我的通关代码: 测试结果: 任务描述 本关任务:实现二叉排序树的基本算法。 相关知识 为了完成本关任务,你需要掌握:二叉树的创建、查找和删除算法。具体如下: (1)由关键字序列(4,9,0,1,8,6,3,5,2,7)创建一棵二叉排序树bt并以括号表示法输出。 (2)判断bt是否为一棵二叉排序树。 (3)采用递归方法查找关键字为6的结点,并输出其查找路径。 (4)分别删除bt中关键
383 11
【C++数据结构——查找】二叉排序树(头歌实践教学平台习题)【合集】
|
存储 人工智能 算法
【C++数据结构——图】最短路径(头歌教学实验平台习题) 【合集】
任务描述 本关任务:编写一个程序,利用Dijkstra算法,实现带权有向图的最短路径。 相关知识 为了完成本关任务,你需要掌握:Dijkst本关任务:编写一个程序,利用Dijkstra算法,实现带权有向图的最短路径。为了完成本关任务,你需要掌握:Dijkstra算法。带权有向图:该图对应的二维数组如下所示:Dijkstra算法:Dijkstra算法是指给定一个带权有向图G与源点v,求从v到G中其他顶点的最短路径。Dijkstra算法的具体步骤如下:(1)初始时,S只包含源点,即S={v},v的距离为0。
236 15
|
Java C++
【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
468 12
|
C++
【C++数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
本文档介绍了如何根据二叉树的括号表示串创建二叉树,并计算其结点个数、叶子结点个数、某结点的层次和二叉树的宽度。主要内容包括: 1. **定义二叉树节点结构体**:定义了包含节点值、左子节点指针和右子节点指针的结构体。 2. **实现构建二叉树的函数**:通过解析括号表示串,递归地构建二叉树的各个节点及其子树。 3. **使用示例**:展示了如何调用 `buildTree` 函数构建二叉树并进行简单验证。 4. **计算二叉树属性**: - 计算二叉树节点个数。 - 计算二叉树叶子节点个数。 - 计算某节点的层次。 - 计算二叉树的宽度。 最后,提供了测试说明及通关代
249 10
|
算法 C++
【C++数据结构——图】最小生成树(头歌实践教学平台习题) 【合集】
【数据结构——图】最小生成树(头歌实践教学平台习题)目录 任务描述 相关知识 测试说明 我的通关代码: 测试结果:【合集】任务描述 本关任务:编写一个程序求图的最小生成树。相关知识 为了完成本关任务,你需要掌握:1.建立邻接矩阵,2.Prim算法。建立邻接矩阵 上述带权无向图对应的二维数组,根据它建立邻接矩阵,如图1建立下列邻接矩阵。注意:INF表示无穷大,表示整数:32767 intA[MAXV][MAXV];Prim算法 普里姆(Prim)算法是一种构造性算法,从候选边中挑
242 10
|
存储 算法 C++
【C++数据结构——图】图的邻接矩阵和邻接表的存储(头歌实践教学平台习题)【合集】
本任务要求编写程序实现图的邻接矩阵和邻接表的存储。需掌握带权有向图、图的邻接矩阵及邻接表的概念。邻接矩阵用于表示顶点间的连接关系,邻接表则通过链表结构存储图信息。测试输入为图的顶点数、边数及邻接矩阵,预期输出为Prim算法求解结果。通关代码提供了完整的C++实现,包括输入、构建和打印邻接矩阵与邻接表的功能。
663 10
|
C++
【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
423 7
下一篇
开通oss服务