【队列】基于循环数组的实现

Description

请完成以下队列类的实现:(请注意数组实现应该为循环数组)

enum ErrorCode

{

success,

underflow,

overflow

};

const int maxQueue = 100;

template <class QueueEntry>

class MyQueue

{

public:

MyQueue();

bool empty() const;  // 判断队列是否为空

ErrorCode append(const QueueEntry &item);  // 入队操作

ErrorCode serve();// 出队操作

ErrorCode retrieve(QueueEntry &item) const;   // 获取队头元素

bool full() const; // 判断队列是否已满

int size() const; // 获取队列已有元素个数

void clear();  // 清除队列所有元素

ErrorCode retrieve_and_serve(QueueEntry &item);  // 获取队头元素并出队

private:

int front;                             // 队头下标

int rear;                              // 队尾下标

QueueEntry entry[100];       // 队列容器

};

Problem Source: 第二周 5班

解题思路:

实现循环数组

Circular arrays(循环数组)

将数组设想为一个循环的,而非线性的; 用两个下标front和rear记录队头和队尾位置; 添加元素时,rear右移,将元素置于rear位置。当rear等于max时(last index), rear 置 0. 元素出队时,删除位于front位置的元素,然后front右移. 当front 等于 max时, 置 front 为 0。

Boundary conditions

问题:无法区分满队列与空队列。

解决方法:

1. 在数组中空一个位置;

2. 使用一个布尔量表示队列是否满。当rear刚好到达front之前时,置 此标志为true.

3. 使用一个计数器( counter)以记录队列中的元素个数。

此处代码采用第一种解决办法:

1.front始终指向队列第一个元素,即总是放着东西的;

rear始终指向队列的下一个位置,即总是空着的;

2.假设数组开到100,那么队列满时,实际长度为99,判断为满:(rear + 1) % 100 == front

判断为空:front==rear

3.当排到数组尾部,要跳到头部来继续进行循环。

实现代码:

enum ErrorCode {
    success,
    underflow,
    overflow
};

const int maxQueue = 100;

template <class QueueEntry>
class MyQueue
{
public:
         MyQueue();
         bool empty() const;
         ErrorCode append(const QueueEntry &item);
         ErrorCode serve();
         ErrorCode retrieve(QueueEntry &item) const;
         bool full() const;
         int size() const;
         void clear();
         ErrorCode retrieve_and_serve(QueueEntry &item);
private:
         int front;
         int rear;
         QueueEntry entry[100];
};

template <class QueueEntry>
MyQueue<QueueEntry>::MyQueue() {      //初始化
      front = rear = 0;
}

template <class QueueEntry>
bool MyQueue<QueueEntry>:: empty() const {   //判断队列是否为空
     if (front == rear) return true;
     else return false;
}

template <class QueueEntry>
ErrorCode MyQueue<QueueEntry>::append(const QueueEntry &item) {//入队
    if (full()) {
        return overflow;
    } else {
        entry[rear] = item;
        rear++;
        if (rear  == 100) rear = 0;//从数组头部继续进行循环
        return success;
    }
}

template <class QueueEntry>
ErrorCode MyQueue<QueueEntry>::serve() {  //出队
    if (empty()) {
        return underflow;
    } else {
        front++;
        if (front == 100) front = 0;
        return success;
    }
}

template <class QueueEntry>
ErrorCode MyQueue<QueueEntry>::retrieve(QueueEntry &item) const {  //取队头
     if (empty()) {
         return underflow;
     } else {
         item = entry[front];
         return success;
     }
}

template <class QueueEntry>
bool MyQueue<QueueEntry>::full() const {  //判断队列是否已满
     if ((rear + 1) % 100 == front) return true;
     else return false;
}

template <class QueueEntry>
int MyQueue<QueueEntry>::size() const {  //判断队的长度
    if (front <= rear) {
        return (rear - front);
    } else {
      return (100 - front + rear);
    }
}

template <class QueueEntry>
void MyQueue<QueueEntry>::clear() {  //清除队列
    rear = front = 0;
}

template <class QueueEntry>
ErrorCode MyQueue<QueueEntry>::retrieve_and_serve(QueueEntry &item) {//取队头并出队
    ErrorCode flag;
    flag = retrieve(item);
    serve();
    return flag;
}                                 

(本博文或多或少参考过其他网上资料,但时间已久忘记当初的参考了,在此对他们表示感谢!)

时间: 2024-12-15 06:50:23

【队列】基于循环数组的实现的相关文章

基于循环数组的无锁队列

在之前的两篇博客(线程安全的无锁RingBuffer的实现,多个写线程一个读线程的无锁队列实现)中,分别写了在只有一个读线程.一个写线程的情况下,以及只有一个写线程.两个读线程的情况下,不采用加锁技术,甚至原子运算的循环队列的实现.但是,在其他的情况下,我们也需要尽可能高效的线程安全的队列的实现.本文实现了一种基于循环数组和原子运算的无锁队列.采用原子运算(compare and swap)而不是加锁同步,可以很大的提高运行效率.之所以用循环数组,是因为这样在使用过程中不需要反复开辟内存空间,可

JAVA实现数组队列,循环数组队列,链式队列

/** * 文件名:QueueText.java * 时间:2014年10月22日下午9:05:13 * 作者:修维康 */ package chapter3; /** * 类名:ArrayQueue * 说明:队列的数组实现 */ class ArrayQueue<AnyType>{ private static final int DEFAULT_CAPACITY = 10; private int front;//队头 private int rear;//队尾 private int

队列的循环数组实现

这里初始化的队列的front一直指向队头,rear一直指向队尾. 1 #include "pch.h" 2 #include <iostream> 3 #include <stdlib.h> 4 using namespace std; 5 6 #define MinQueueSize 5 //限定队列的最小容量 7 8 struct QueueRecord //记录队列的相关信息 9 { 10 int cap; 11 int front; 12 int rea

循环队列(循环数组)中元素个数的计算

队列头指针为front,队列尾指针为rear(指向队尾元素),after_rear为队尾元素的后一位置(按顺时针方向),队列容量为maxsize   如果用 front == rear 来表示队列为空,也就是说front和rear指向同一个位置,那么: 队列满时:(rear+1) mod maxsize == front 队列中元素个数为:(rear-front+maxsize) mod maxsize   如果用 rear == (front-1+maxsize) mod maxsize 来表

前端开发:setTimeout与setInterval 定时器与异步循环数组

前端开发:setTimeout与setInterval 定时器与异步循环数组 前言: 开通博客园三个月以来,随笔记录了工作中遇到的大大小小的难题,也看过无数篇令人启发的文章,我觉得这样的环境是极好的,在与博友的分享中可以学到新的知识.得到先驱者的指正.解决工作中遇到的难题.近一个月工作繁忙,新的文章也迟迟未写,今天呢,过来深入了解一下 关于javascript定时器的知识: setTimeout与setInterval简述 setTimeout与setInterval使用方法基本相同,他们接受两

数据结构Java实现07----队列:顺序队列&amp;顺序循环队列、链式队列、顺序优先队列

数据结构Java实现07----队列:顺序队列&顺序循环队列.链式队列.顺序优先队列 一.队列的概念: 队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在其一端进行插入操作在其另一端进行删除操作. 队列中允许进行插入操作的一端称为队尾,允许进行删除操作的一端称为队头.队列的插入操作通常称作入队列,队列的删除操作通常称作出队列. 下图是一个依次向队列中插入数据元素a0,a1,...,an-

数据结构6_顺序队列(循环队列)

本文实现了顺序队列,与链队列不同的是,顺序队列需要考虑一个问题, 问题情况如下, 解决办法:循环队列,当rear到分配的数组空间末尾时,转到数组头 但是当q.rear==q.front时,又如何区分一种是空队列,一种是满队列的情况呢 这里有两种方案 本次代码实现了第一种方法,同时设置了一个技术变量length,稍加改动便可实现第二个方法 代码如下: #include<iostream>using namespace std;//该顺序队列为循环队列,解决队尾指针达到最大值,队列中有空闲单元,但

数据结构基础(5)--队列和循环队列详解--静态方式

队列的具体应用: 所有和事件有关的操作都有队列的影子. (例如操作系统认为先进来的先处理) 定义: 一种可是实现"先进先出"的存储结构 分类: 链式队列:用链表实现 静态队列:用数组实现 静态队列通常都必须是循环队列,为了减少 内存浪费. 循环队列 : 1.静态队列为什么必须是循环队列 如果用传统意义的数组实现队列,无论入队还是出队,rear和front指针只能+不能-: 比 F元素下标小的的数组元素下标就浪费了. 循环队列怎么用呢? 当出现这种情况时,如果仍然需要插入元素,那么f指向

数据结构_线性表_顺序队列_循环队列_链队列

个位看官,由于队列操作相对简单,我啥也不多说,直接上代码,欢迎验证!!! #pragma mark --abstract //队列(queue)是只允许在表的一端进行插入,在表的另一端进行删除的线性表,允许插入的一端称为队尾(rear) //允许删除的一端叫做队头(font),不含元素的队列称为空队列 //队列的特点是先进先出(FIFO线性表) #pragma mark --分类 //1.队列的顺序存储结构称为顺序队列(sequential queue),他是由存放队列的一维数组和分别指向队头和