循环队列

1. 循环队列的概念

在实际使用队列时,为了使队列空间能重复使用,往往对队列的使用方法稍加改进:无论插入或删除,一旦rear指针增1或front指针增1 时超出了所分配的队列空间,就让它指向这片连续空间的起始位置,自动从MaxSize-1增1变到0,可用取余运算rear%MaxSize和front%MaxSize来实现。这实际上是把队列空间想象成一个环形空间,环形空间中的存储单元循环使用,用这种方法管理的队列也就称为循环队列。

循环队列就是将队列存储空间的最后一个位置转而绕到第一个位置,形成逻辑上的环状空间,但我们需要注意,实际上循环队列不是一个真正的环,它依旧是单线性的。

使用循环队列虽然可以解决顺序队列中浪费内存的问题,但这里任然存在一个问题,就是对于循环队列而言,队空和队满的条件都是rear==front,导致两种情况无法区分。 为了区分队空和队满,可以采用空一个元素不使用的方法,此时队空的条件为:front==rear,而队满的条件则为:(rear+1)%MAXSIZE == front,从而加以区分。

 

2. 代码实现

在数组实现的顺序链表基础上进行改进

#include<stdio.h>
#include<stdlib.h>

typedef struct Qnode
{
    int *Data;
    int Front,Rear;
    int Max;
} *Queue;

//创建一个空队列
Queue CreateQueue(int max)
{
    Queue q = (Queue)malloc(sizeof(struct Qnode));
	q->Data = (int *)malloc(sizeof(int) * max);
	q->Front = q->Rear=0;
    q->Max = max;
    return q;
}

//入队
void AddQueue(Queue q, int data)
{
	if ((q->Rear+1)%q->Max == q->Front)
    {
        printf("ERROR: Queue is full!\n");
    }
    else
    {
        //只能填充MAX-1个数据,永远有一个格子没有数据
        q->Rear = (q->Rear+1)%q->Max;
        q->Data[q->Rear] = data;
        printf("add queue data = %d\n", data);
    }
}
//出队
void OutQueue(Queue q, int *data)
{
    if(q->Front == q->Rear)
    {
        printf("ERROR: Queue is empty\n");
    }
    else
	{
         q->Front = (q->Front+1)%q->Max;
        *data = q->Data[q->Front];
    }
}
int main()
{
    int i, temp;
    Queue q;
    
    q=CreateQueue(10);       //创建一个队长为10的空队列    
    //for(i=0;i<10;i++)      //入队10个数字是不可以的,入队第10个数字时会报错队列已满
	for(i=0;i<9;i++)        //一次最多只能入队9个数字,因为环形队列有一个格子是要空着的
        AddQueue(q,i);
    for(i=0;i<5;i++)	//出队5个数字并打印
    {
        OutQueue(q, &temp);
        printf("%d\n", temp);
    }
    return 0;
}

3. 总结

数组实现的顺序链表因为空间不能重复使用,实际工作中基本没啥用处,直接PASS;

链表实现的顺序链表空间是可以重复使用的,但是每次入队和出队动作都需要动态申请内存,这对于频繁进行入队和出队的程序来说,是非常影响其效率的;

循环链表是在数组实现的顺序链表上做了些许改进而得到的,它的空间可以重复使用,入队和出队也不需要动态申请内存,所以这种方式在实际工作当中使用得最广泛。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值