循环队列 与 其基本操作

来源:互联网 发布:mac压缩包加密 编辑:程序博客网 时间:2024/05/16 06:21

(一)循环队列的代码实现

#include<iostream>#include<cstdio>#include<cstdlib>#define MAXSIZE 100using namespace std;int e;int count;typedef struct{int *base;int front;int rear;//int count;}SqQueue;int InitQueue(SqQueue &Q){//构造一个空队列Q.base=(int*)malloc(MAXSIZE*sizeof(int));if(!Q.base)return 0;//存储空间分配失败 Q.front=Q.rear=0;return 1; }int QueueLength(SqQueue Q){//返回Q的元素个数,即队列长度 return (Q.rear-Q.front+MAXSIZE)%MAXSIZE;}int EnQueue(SqQueue &Q,int e){//插入元素e为Q的新的队尾元素if((Q.rear+1)%MAXSIZE==Q.front)return 0;Q.base[Q.rear]=e;Q.rear=(Q.rear+1)%MAXSIZE; return 1;}int DeQueue(SqQueue &Q,int &e){//若队列不空,删除Q的对头元素,用e返回其值//否则返回0 if(Q.front==Q.rear)return 0;e=Q.base[Q.front];Q.front=(Q.front+1)%MAXSIZE;return 1;}void print(SqQueue cq){for(int i=0;i<count;i++){//【1】 //错误:此处必须用一个变量count存储元素数量DeQueue(cq,e);//否则随着算法的执行,每次删除队列中的一个元素,for的第二个判断条件也会改变 printf("%d ",e);}printf("\n");}int main(){int n;SqQueue cq;InitQueue(cq);while(true){scanf("%d",&n);if(n==0)break;EnQueue(cq,n);}count=QueueLength(cq);printf("%d\n",count);print(cq);return 0;}

自己写这个饭的一个错误,【1】处的print函数,要获取队列的元素个数,必须在队列打印输出(取出队头元素)之前,用一个count变量存储队列的元素个数,而不能直接写QueueLength,否则随着算法的执行,每次删除队列中的一个元素,for的第二个判断条件也会改变 ,结果只能打印出一半元素。


这里注意几点:

(1)循环队列判满条件:(rear+1)%MAXSIZE==front

(2)队列判空条件:front==rear

(3)rear与front的值都会不断改变,删除元素:front+1,插入元素:rear+1。随着rear和front不断追逐,会产生两个结果

<1>当rear追到front:队列满

<2>当front追到rear:队列为空

(4)循环队列实际可可插入最大元素数为:MAXSIZE-1,rear总是指向队列最后一个元素的下一个位置,并且队列中只要有元素存在,就不会出现front=rear的情况,所以,当循环队列为满时,只可能出现下图所示的情况:



附上wiki:https://zh.wikipedia.org/wiki/%E7%92%B0%E5%BD%A2%E7%B7%A9%E8%A1%9D%E5%8D%80


(二)循环队列的实际应用:

一个比较实用的就是编写电脑的缓冲区

//初始化缓冲区Buffervoid InitBuffer(void){InitQueue(Q)   // 构造具有N个缓冲区的空队列Q}void Producer(void)   //生产者进程do{//生产一个数据e;if(QueueFull(Q)  // 队列满时,等待消费者取走数据的通知;     wait(message_from_Consumer);  EnQueue(Q,e) ; // 收到通知后,将数据e插入到队列Q的队尾;signal(message_to_Consumer); // 向消费者发出生产数据通知;}while(true); }void Consumer(void){   //消费者进程do{if(QueueEmpty(Q))  // 队列空时,等待生产者生产数据       wait(message_from_ Producer);  //等待已生产 通知DeQueue(Q,e)  //收到通知后,将数据e从队列中取走Consume(e);  // 消费者进程加工数据signal(message_to_ Producer)                       //向生产者发出已取走数据的通知;} while (true); }






原创粉丝点击