educoder数据结构与算法 队列 第2关 实现一个链接存储的队列

简介: educoder数据结构与算法 队列 第2关 实现一个链接存储的队列

任务描述

本关任务:实现 step2/CLnkQueue.cpp 中的CLQ_IsEmptyCLQ_LengthCLQ_InCLQ_Out四个操作函数,以实现判断队列是否为空、求队列长度、队列元素入队和出队等功能。

相关知识

链式队列的定义

队列的存储除了顺序存储之外也可以采用链接存储方式来实现。图 1 描述了队列的一种链接存储实现方案。

该队列存储了 3 个元素 {56,77,15} ,其中 56 为队列头, 15 为队列尾。

这种实现方案中涉及到的两个属性元素如下:

  • rear: 指向队列尾结点的指针;
  • next: 指向队列头结点的指针。

当队列是空队列时,rear指向附加头结点,附加头结点的数据项等于 0 ,如图 2 所示。

基于这些属性要素组织成的链表结点的结构定义为:

  1. struct LNode {
  2. T data;
  3. LNode* next;
  4. };


为了讨论简单,我们假设队列元素的数据类型为整数:

  1. typedef int T; // 队列元素的数据类型


据此,只要给定rear指针,我们就可以对队列进行入队和出队的操作。

  • 在给定图 1 的状态下,进队一个元素 25 以后的状态如图 3 所示:

  • 若出队一个元素是指将当前队列头结点去掉。则在给定图 3 的状态下,进行一次出队后的状态如图 4 所示:

链式队列的主要操作


对数据元素进行操作处理是一个数据结构的重要组成部分。队列涉及的主要操作如下:


创建队列:创建一个队列。具体操作函数定义如下: LNode* CLQ_Create();


释放队列空间:释放队列所占用的空间,其中rear指向尾结点。具体操作函数定义如下: void CLQ_Free(LNode* rear);


置空队列:将队列变为空队列,其中rear指向尾结点。具体操作函数定义如下: void CLQ_MakeEmpty(LNode* & rear);


判断队列是否为空:若队列为空,则返回 true,否则返回false。具体操作函数定义如下: bool CLQ_IsEmpty(LNode* rear);


求队列长度:获取队列的长度,其中rear指向尾结点。具体操作函数定义如下: int CLQ_Length(LNode* rear);


新结点入队列:新结点加入链表尾部,其中rear指向尾结点。具体操作函数定义如下: void CLQ_In(LNode* & rear, T x);


队列元素出队列:item为出队的元素的值。若出队成功(队列不为空),则返回true;否则(队列空),返回false。具体操作函数定义如下: bool CLQ_Out(LNode* & rear, T& item);


获取队列头结点元素:若获取失败(队列空),则返回值为false,否则返回值为true。具体操作函数定义如下: bool CLQ_Head(LNode* rear, T& item);


打印队列:依次打印出队列中的每个元素。具体操作函数定义如下: void CLQ_Print(LNode* rear)。


编程要求


本关任务是实现 step2/CLnkQueue.cpp 中的CLQ_IsEmpty、CLQ_Length、CLQ_In和CLQ_Out四个操作函数,以实现判断队列是否为空、求队列长度、队列元素入队和出队等功能。具体要求如下:


CLQ_IsEmpty:判断队列是否为空,若队列为空,则返回true,否则返回false;


CLQ_Length:获取队列的长度;


CLQ_In:新结点加入链表尾部;


CLQ_Out:队列元素出队列,若出队成功(队列不为空),则返回true;否则(队列空)返回false;


输入输出格式请参见后续说明及测试样例。


注意:本关必读中提及的其他操作已经由平台实现,你在实现本关任务的四个操作函数时,在函数体内可调用其他操作。


本关涉及的代码文件 CLnkQueue.cpp 中的 4 个操作函数的代码框架如下:


bool CLQ_IsEmpty(LNode* rear)

// 判断队列是否为空

{

// 请在这里补充代码,完成本关任务

/********** Begin *********/

/********** End **********/

}

int CLQ_Length(LNode* rear)

// 返回队列长度,rear指向尾结点

{

// 请在这里补充代码,完成本关任务

/********** Begin *********/

/********** End **********/

}

void CLQ_In(LNode* & rear, T x)

// 入队列, 新结点加入链表尾部。rear指向尾结点

{

// 请在这里补充代码,完成本关任务

/********** Begin *********/

/********** End **********/

}

bool CLQ_Out(LNode* & rear, T& item)

// 出队列。空队列时,返回值为false。rear指向尾结点

{

// 请在这里补充代码,完成本关任务

/********** Begin *********/

/********** End **********/

}


测试说明

本关的测试文件是 step2/Main.cpp ,负责对你实现的代码进行测试。具体代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "CLnkQueue.h"
#pragma warning(disable:4996)
int main()
{
LNode* rear=CLQ_Create();
char dowhat[100];
while(true) {
scanf("%s", dowhat);
if (!strcmp(dowhat,"in")) {
T x;
scanf("%d", &x);
CLQ_In(rear,x);
}else if (!strcmp(dowhat,"out")) {
T item;
CLQ_Out(rear, item);
}
else {
break;
}
}
int length=CLQ_Length(rear);
printf("Queue length: %d\n", length);
printf("Queue data: ");
CLQ_Print(rear);
CLQ_Free(rear);
}

注意:step2/Main.cpp 的代码不能被修改。


输入输出说明: 输入格式: 输入多个操作:如果输入 “in” ,则后面跟一个数 x ,表示 x 入队列;如果输入 “out” ,表示出队列操作;如果输入 “end” ,表示输入结束。


输出格式: 输出队列长度,然后从队头到队尾依次输出队列的各元素。


以下是平台对 step2/Main.cpp 的测试样例: 样例输入: in 1 in 3 in 5 in 9 in 12 out end 样例输出 Queue length: 4 Queue data: 3 5 9 12


开始你的任务吧,祝你成功!


人生,对于我们谁都有许多想法,但由于迟迟没有付诸行动,结果多少光阴过去,却只能停留在计划中,要想拥有成功,就需要赋予人生足够的速度,这是成功者的姿态,也是胜利者的姿态。

AC_Code

/
// 队列的链接存储实现文件。
// 采用循环链表,具有附加头节点,使用尾结点指针。
// CLQ_   Circularly Linked Queue
#include <stdio.h>
#include <stdlib.h>
#include "CLnkQueue.h"
LNode* CLQ_Create()
// 创建一个队列。
{
    LNode* rear=(LNode*)malloc(sizeof(LNode));
    rear->data = 0;
    rear->next = rear;
    return rear;
}
void CLQ_Free(LNode* rear)
// rear指向尾结点。
{
    CLQ_MakeEmpty(rear);
    free(rear);
}
void CLQ_MakeEmpty(LNode* & rear)
// rear指向尾结点。
// 将队列变为空队列。
{
    T item;
    while(!CLQ_IsEmpty(rear))
        CLQ_Out(rear,item);
}
bool CLQ_IsEmpty(LNode* rear)
// 判断队列是否为空。
{
    // 请在Begin-End之间补充代码,完成队列是否为空的判断。
    /********** Begin *********/
    return rear==rear->next;
    /********** End **********/
}
int CLQ_Length(LNode* rear)
// 返回队列长度,rear指向尾结点。
{
    // 请在Begin-End之间补充代码,获取队列长度。
    /********** Begin *********/
    return rear->next->data;
    /********** End **********/
}
void CLQ_In(LNode* & rear, T x)
// 入队列, 新结点加入链表尾部。rear指向尾结点。
{
    // 请在Begin-End之间补充代码,完成新结点入队操作。
    /********** Begin *********/
    LNode*newNode=new LNode;
    newNode->data=x;
    newNode->next=rear->next;
    rear->next=newNode;
    rear=newNode;
    rear->next->data++;
    /********** End **********/
}
bool CLQ_Out(LNode* & rear, T& item)
// 出队列。空队列时,返回值为false。rear指向尾结点。
{
    // 请在Begin-End之间补充代码,完成结点出队操作。
    /********** Begin *********/
if(CLQ_IsEmpty(rear))  return false;
    else if(rear->next->data==1) 
    {
        rear=rear->next;
        rear->next=rear;
        rear->data--;
    }
    else
    {
        LNode* addNode=rear->next;
        addNode->next=addNode->next->next;
        addNode->data--;
        return true;
    }
    /********** End **********/
}
bool CLQ_Head(LNode* rear, T& item)
// rear指向尾结点。
// 获取队列头。空队列时返回值为false。
{
    if (CLQ_IsEmpty(rear)) 
        return false;
    item = rear->next->next->data;
    return true;
}
void CLQ_Print(LNode* rear)
// 打印队列。
{
    if (CLQ_IsEmpty(rear))  {
        printf("The queue is: empty. \n");
        return;
    }
    LNode* node=rear->next->next;
    do {
        printf("%d  ", node->data);
        node = node->next;
    }   while (node != rear->next); 
    //printf("\n");
}
相关文章
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
1116 9
|
10月前
|
前端开发 Java
java实现队列数据结构代码详解
本文详细解析了Java中队列数据结构的实现,包括队列的基本概念、应用场景及代码实现。队列是一种遵循“先进先出”原则的线性结构,支持在队尾插入和队头删除操作。文章介绍了顺序队列与链式队列,并重点分析了循环队列的实现方式以解决溢出问题。通过具体代码示例(如`enqueue`入队和`dequeue`出队),展示了队列的操作逻辑,帮助读者深入理解其工作机制。
319 1
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
605 77
232.用栈实现队列,225. 用队列实现栈
在232题中,通过两个栈(`stIn`和`stOut`)模拟队列的先入先出(FIFO)行为。`push`操作将元素压入`stIn`,`pop`和`peek`操作则通过将`stIn`的元素转移到`stOut`来实现队列的顺序访问。 225题则是利用单个队列(`que`)模拟栈的后入先出(LIFO)特性。通过多次调整队列头部元素的位置,确保弹出顺序符合栈的要求。`top`操作直接返回队列尾部元素,`empty`判断队列是否为空。 两题均仅使用基础数据结构操作,展示了栈与队列之间的转换逻辑。
|
12月前
|
算法 调度 C++
STL——栈和队列和优先队列
通过以上对栈、队列和优先队列的详细解释和示例,希望能帮助读者更好地理解和应用这些重要的数据结构。
281 11
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
482 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
12月前
|
DataX
☀☀☀☀☀☀☀有关栈和队列应用的oj题讲解☼☼☼☼☼☼☼
### 简介 本文介绍了三种数据结构的实现方法:用两个队列实现栈、用两个栈实现队列以及设计循环队列。具体思路如下: 1. **用两个队列实现栈**: - 插入元素时,选择非空队列进行插入。 - 移除栈顶元素时,将非空队列中的元素依次转移到另一个队列,直到只剩下一个元素,然后弹出该元素。 - 判空条件为两个队列均为空。 2. **用两个栈实现队列**: - 插入元素时,选择非空栈进行插入。 - 移除队首元素时,将非空栈中的元素依次转移到另一个栈,再将这些元素重新放回原栈以保持顺序。 - 判空条件为两个栈均为空。
|
12月前
|
缓存 监控 算法
内网监控管理软件:PHP 语言队列算法揭秘
在数字化办公环境中,内网监控管理软件对企业的稳定运行和信息安全至关重要。本文深入介绍PHP中的队列算法及其在内网监控软件中的应用,包括监控数据收集、任务调度和日志记录等场景,通过代码示例展示其实现方法。队列算法可提高性能、保证数据顺序并实现异步处理,为企业提供高效的安全保障。
206 1
|
存储 算法 C++
【C++数据结构——图】图的邻接矩阵和邻接表的存储(头歌实践教学平台习题)【合集】
本任务要求编写程序实现图的邻接矩阵和邻接表的存储。需掌握带权有向图、图的邻接矩阵及邻接表的概念。邻接矩阵用于表示顶点间的连接关系,邻接表则通过链表结构存储图信息。测试输入为图的顶点数、边数及邻接矩阵,预期输出为Prim算法求解结果。通关代码提供了完整的C++实现,包括输入、构建和打印邻接矩阵与邻接表的功能。
615 10
|
存储 C语言 C++
【C++数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现链栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储整数,最大
272 9