实现一个链接存储的队列

本文介绍了如何在C++中实现链式队列的四个基本操作:判断队列是否为空、求队列长度、元素入队和出队。通过rear和next指针管理队列状态,并给出了编程要求和测试说明。
摘要由CSDN通过智能技术生成

任务描述

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

相关知识
链式队列的定义

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

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

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

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

特别说明:空间的开始地址为data,连续空间里的位置编号从data所指的开始位置起,到该空间的结束位置,编号依次是0,1,2,…,max-1。在图1的示例中max=6。下一个出队元素(这里是队列的头结点)所存储的位置编号用front给出,下一个入队元素应存储的位置编号用rear给出。

当队列是空队列时,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_IsEmptyCLQ_LengthCLQ_InCLQ_Out四个操作函数,以实现判断队列是否为空、求队列长度、队列元素入队和出队等功能。具体要求如下:

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

  • CLQ_Length:获取队列的长度;

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

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

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

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

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

 
  1. bool CLQ_IsEmpty(LNode* rear)
  2. // 判断队列是否为空
  3. {
  4. // 请在这里补充代码,完成本关任务
  5. /********** Begin *********/
  6. /********** End **********/
  7. }
 
  1. int CLQ_Length(LNode* rear)
  2. // 返回队列长度,rear指向尾结点
  3. {
  4. // 请在这里补充代码,完成本关任务
  5. /********** Begin *********/
  6. /********** End **********/
  7. }
 
  1. void CLQ_In(LNode* & rear, T x)
  2. // 入队列, 新结点加入链表尾部。rear指向尾结点
  3. {
  4. // 请在这里补充代码,完成本关任务
  5. /********** Begin *********/
  6. /********** End **********/
  7. }
 
  1. bool CLQ_Out(LNode* & rear, T& item)
  2. // 出队列。空队列时,返回值为false。rear指向尾结点
  3. {
  4. // 请在这里补充代码,完成本关任务
  5. /********** Begin *********/
  6. /********** End **********/
  7. }
测试说明

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

 
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "CLnkQueue.h"
  5. #pragma warning(disable:4996)
  6. int main()
  7. {
  8. LNode* rear=CLQ_Create();
  9. char dowhat[100];
  10. while(true) {
  11. scanf("%s", dowhat);
  12. if (!strcmp(dowhat,"in")) {
  13. T x;
  14. scanf("%d", &x);
  15. CLQ_In(rear,x);
  16. }else if (!strcmp(dowhat,"out")) {
  17. T item;
  18. CLQ_Out(rear, item);
  19. }
  20. else {
  21. break;
  22. }
  23. }
  24. int length=CLQ_Length(rear);
  25. printf("Queue length: %d\n", length);
  26. printf("Queue data: ");
  27. CLQ_Print(rear);
  28. CLQ_Free(rear);
  29. }


#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->next == rear;

    /********** 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* p = new LNode;
    p->data = x;
    p->next = rear->next;
    rear->next = p;
    rear = p;
    rear->next->data++;
   

    /********** End **********/
}

bool CLQ_Out(LNode*& rear, T& item)
// 出队列。空队列时,返回值为false。rear指向尾结点。
{
    // 请在Begin-End之间补充代码,完成结点出队操作。
    /********** Begin *********/
    if (CLQ_IsEmpty(rear)) return false;
    if(rear->next->data==1)
       {
           rear=rear->next;
           rear->next=rear;
           rear->data--;
       }else
       {
             LNode* p = rear->next;
             p->next = p->next->next; 
             p->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");
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值