循环队列-双端和单端
单循环队列
-  
q :用数组来记录数据
 -  
cap:代表数组的长度
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。 -  
len:代表元素的个数,取尾部元素可以根据头元素指针和这个值来进行计算
(queue->head+queue->len)%queue->cap ,
取余是为了在规定范围内循环使用有限空间
 -  
head:头元素的指针
 
-  
出队:出头元素只需要将head往前移动即可,注意也要取余, 同时len需要减一
 -  
入队:入队只需要赋值给 (queue->head+queue->len)%queue->cap位置的值即可,同时 len++,也就是说 tail=(queue->head+queue->len)%queue->cap) 永远指向尾部元素的后一个待赋值的位置
 
#include <iostream>
using namespace std;
struct  Queue{
	
	int* q;
	int cap;
	int len;
	int head;
};
Queue* Create(int cap){
	Queue* queue = (Queue*)malloc(sizeof(Queue));
	queue->q = (int*)calloc(cap,sizeof(int));
	queue->len=0;
	queue->cap=cap;
	queue->head=0;
	return queue;
}
bool isFull(Queue* queue){
	return queue->cap==queue->len; 
}
bool isEmpty(Queue* queue){
	return queue->len==0;
}
bool enQueue(Queue* queue,int val){
	 if(isFull(queue))
	 	return false;
	 
	 queue->q[(queue->head+queue->len)%queue->cap] = val;
	 
	 queue->len++;
	 
	 return true;	 
}
int deQueue(Queue* queue){
	if(isEmpty(queue))
		return -1;
	int r = queue->q[queue->head];
	queue->head = (queue->head+1)%queue->cap;
	queue->len--;
	return r;
}
int Front(Queue* queue){
	if(isEmpty(queue))
		return -1;
	return queue->q[queue->head] ;	
}
int Rear(Queue* queue){
	if(isEmpty(queue))
		return -1;
	return queue->q[(queue->head+queue->len-1)%queue->cap];
}
int main(int argc, char *argv[])
{
	Queue* queue = Create(4);
	enQueue(queue,1);
 	enQueue(queue,2);
 	enQueue(queue,3);
 	cout<<enQueue(queue,4)<<endl;
 	cout<<enQueue(queue,5)<<endl;
 	
 	cout<<"----------------\n";
 	
 	cout<<deQueue(queue)<<endl; 
 	cout<<deQueue(queue)<<endl; 
 	cout<<Rear(queue)<<"  "<<Front(queue)<<endl; 
 	
 	
 	
	return 0;
}
 
双端循环队列
- head:指向头元素指针
 - tail:指向尾部元素的后一个待赋值的位置
 - q:数据数组指针
 - length:元素个数
 - N:数组容量, 比设定的容量大一
 
为什么N不设置为cap,因为需要留一个位置判断队满
-  
左入:head永远指向左边的头元素,head向左移动,(queue->head-1+queue->N)%queue->N ,然后赋值。+N是为了防止出席那负数
 -  
左出:head向右移动,(queue->head+1+queue->N)%queue->N,
 -  
右入:赋值 然后tail向右移动, (queue->tail+1+queue->N)%queue->N,为什么tail先赋值,因为tail永远指向右边尾元素的下一个待赋值的元素的位置。
 -  
右出:tail向左移动,(queue->tail-1+queue->N)%queue->N;
 -  
判满:因为开辟队列的时候多留了一个位置,所以如果 ((queue->tail+1)%queue->N)==queue->head,则队列满了
 -  
判空:因为刚开始 tail=head=0,所以是空的,如果在移动的过程中出现空了,也就是说 head追上了tail的位置,就代表队列空了
 
#include <iostream>
#include <limits.h> 
using namespace std;
#define SIZE 5
struct Dequeue{
	int head;
	int tail;
	int N;  //为啥多一个 因为%运算之后能达到SIZE。 比如4 那么只能到3 
	int* q;
	int length;	
};
Dequeue* Create(int k){
	Dequeue* queue = (Dequeue*)malloc(sizeof(Dequeue));
	queue->head=0;
	queue->tail=0;
	queue->length=0;
	queue->q = (int*)calloc(queue->N,sizeof(int));
	queue->N = k+1;
	return queue;
}
bool isEmpty(Dequeue* queue){
	return queue->head==queue->tail;
}
bool isFull(Dequeue* queue){
	return ((queue->tail+1)%queue->N)==queue->head;
}
bool Lpush(Dequeue* queue,int val){
	if(isFull(queue))
		return false;
	
	queue->head = (queue->head-1+queue->N)%queue->N;
	queue->q[queue->head] = val;
	return true;
}
bool Rpush(Dequeue* queue,int val){
	if(isFull(queue))
		return false;
		
	
	queue->q[queue->tail] = val;
	queue->tail = (queue->tail+1+queue->N)%queue->N;
	return true;
}
int Lpop(Dequeue* queue){
	if(isEmpty(queue))
		return -1;
	int r = queue->q[queue->head];
	queue->head = (queue->head+1+queue->N)%queue->N;
	return r;
}
int Rpop(Dequeue* queue){
	if(isEmpty(queue))
		return -1;
	queue->tail = (queue->tail-1+queue->N)%queue->N;	
	return queue->q[queue->tail];
}
int getFront(Dequeue* queue){
	if(isEmpty(queue))
		return -1;	
	return queue->q[queue->head];
}
int getRear(Dequeue* queue){
	if(isEmpty(queue))
		return -1;
	return queue->q[(queue->tail-1+queue->N)%queue->N];			
}
int main(int argc, char *argv[])
{
	Dequeue* q = Create(4);
	Lpush(q,1);
	Lpush(q,2);
	Rpush(q,3);
	Rpush(q,4);
	cout<<Lpop(q)<<endl;
	cout<<Rpop(q)<<endl;
	cout<<Lpop(q)<<endl;
	cout<<Rpop(q)<<endl;
	return 0;
}
                    更多精彩
		
													
													
													
													
	
		
