zoukankan      html  css  js  c++  java
  • 循环队列-双端和单端

    单循环队列

    • q :用数组来记录数据

    • cap:代表数组的长度

    • 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<<"----------------
    ";
     	
     	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;
    }
    
  • 相关阅读:
    python--将jenkins配置的任务导出到Excel
    python--终端工具之subprocess
    jquery-触底加载无限滚动
    python-比较字典value的最大值
    Linux-查看cpu核数和个数、查看内存的命令
    python读取本地正在运行的docker容器
    关于get 和post 方法的比较
    git相关的一篇不错的文章
    Java 函数调用是传值还是传引用? 从字节码角度来看看!
    Unity3D移动平台动态读取外部文件全解析
  • 原文地址:https://www.cnblogs.com/biningooginind/p/12763155.html
Copyright © 2011-2022 走看看