循环队列

循环队列

1,循环队列

队列的操作特点是“先进先出”。为充分利用向量空间,克服"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。

在循环队列中,front和rear都是可以移动的。
当队列为空或满时,front = rear都成立,所以不能用这个条件来判断队列是空的还是满的。
为了解决这个问题,在循环队列中有一个约定:
少用一个元素空间,当队尾标识rear在队头标识front的上一个位置时,队列为满。此时,判断队列空和满的条件为:
队空:front== rear;
队满: (rear+1)%MAXNUM== front (MAXNUM为队列容量的大小)

循环队列中front和rear的移动不再是简单的加1,因为原本是循环的,所以可能原本指在末尾,前进一个单位就是又一个循环的开始,故每次移动都要对MAXNUM取模:
front = (front+1)%MAXNUM
rear = (rear+1)%MAXNUM

求队列长度也不是简单的front和rear相减,因为rear的值有可能比front小。
循环队列求队列长度的方法:(rear-front+MAXNUM)%MAXNUM

在这里插入图片描述

在这里插入图片描述

2,C语言实现循环队列
#include<stdio.h>
#include<assert.h>
#define SIZE 8
typedef struct Queue
{
	int elem[SIZE];//数组
	int front;//头
	int rear;//尾
}Queue,*QueueS;

void InitQueueS(QueueS queue)           //初始化
{
    asesrt(queue!=NULL);
    queue->front=0;
    queue->rear=0;
}
bool Push(QueueS queue,int val)         //入队
{
    assert(queue!=NULL);
    if(IsFull(queue))
    {
     return false;
    }
    queue->elem[queu->rear]=val;
    queue->rear=(queue->rear+1)%SIZE;
    return true;
}
bool Pop(QueueS queue,int *rtv)       //出队
{
    assert(queue!=NULL)
    if(IsEmpty(queue))
    {
        return false;
    }
    if(rtv!=NULL)
    {
        *rtv=queue->elem[queue->front];
    }
    queue->front=(queue->front+1)%SIZE;
    return true;
}
void Show(QueueS queue)
{
    for(int i=queue->front;i!=queue->rear;i=(i+1)%SIZE)
    {
        printf("%d ",queue->elem[i]);
    }
    printf("\n");
}
int GetLength(QueueS queue)      //获取长度
{
    return (queue->rear-queu->front+SIZE)%SIZE;
}
bool IsFull(QueueS queue)        //判满
{
    return (queue->rear+1)%SIZE==queue->front;
}
bool IsEmpty(QueueS queue)         //判空
{
    return queue->front==queue->rear;
}
void Clear(QueueS queue)
{
    queue->front=queue->rear;
}
void Destroy(QueueS queue)
{
    Clear(queue);
}
3,OOP实现循环队列
#include<iostream>
using namespace std;
class CQueue
{
public:
    CQueue(int size=10)
    {
        mfront=mrear=0;
        msize=size;
        mqueue=new int[msize];
    }
   /* CQueue(int size=10):mfront(0),mrear(0),msize(size)
    {
        mqueue=new int [msize];
    }
    */
    ~CQueue()
    {
        delete[]mqueue;
        mqueue=NULL;
    }
    CQueue(const CQueue&src)
    {
        mfront=src.mfront;
        mrear=src.mrear;
       mszie=src.msize;
        mqueue=new int [msize];
        for(int i=mfront;i!=mrear;i=(i+1)%msize)
        {
            mqueue[i]=src.mqueue[i];
        }
    }
    void operator=(const CQueue&src)
    {
        if(this==&src)
        {
            return ;
        }
        delete[]mqueue;
        mqueue=NULL;
        mfront=src.mfront;
        mrear=src.mrear;
        mszie=src.msize;
        mqueue=new int [msize];
        for(int i=mfront;i!=mrear;i=(i+1)%msize)
        {
            mqueue[i]=src.mqueue[i];
        }
    }
    void push(int val)
    {
        if(full())
        {
            return;
        }
        mqueue[mrear]=val;
        mrear=(mrear+1)%msize;
    }
    void pop()
    {
        if(empty())
        {
            return;
        }
        mfront=(mfront+1)%msize;
    }
    int front()
    {
        return mqueue[mfront];
    }
    int back()
    {
        if(mrear==0)
        {
            return mqueue[msize-1];
        }
        else
        {
            return mqueue[mrear-1];
        }
    }
    bool full()
    {
        return (mrear+1)%msize==mfront;
    }
    bool empty()
    {
        treturn mrear==mfront;
    }
    void show()
    {
        for(int i=mfront;i!=mrear;i=(i+1)%msize)
        {
            cout<<mqueue[i]<<" ";
        }
    }
 private:
    int*mqueue;
    int mfront;
    int mrear;
    int msize;
    void resize()
    {
        int *mtmp=new int[msize*2];
        for(int i=mfront,j=0;i!=mrear;i=(i+1)%msize,j++)
        {
            mtmp[j]=mqueue[i]
        }
        delete[]mqueue;
        mqueue=mtmp;
        mfront=0;
        mrear=msize-1;
        msize*=2;
    }
};
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值