> 文章列表 > Leetcode 622. 设计循环队列

Leetcode 622. 设计循环队列

Leetcode 622. 设计循环队列

文章目录

  • 1.题目描述
  • 2.原题链接
  • 3.思路分析
  • 4.接口实现 :
    • Front
    • Rear
    • enQueue(value):
    • deQueue():
    • isEmpty(): 检查循环队列是否为空
    • isFull():
    • myCircularQueueFree
  • 5.代码实现

1.题目描述

设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。

需要实现的接口:

MyCircularQueue(k): 构造器,设置队列长度为 k 。
Front: 从队首获取元素。如果队列为空,返回 -1 。
Rear: 获取队尾元素。如果队列为空,返回 -1 。
enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
isEmpty(): 检查循环队列是否为空。
isFull(): 检查循环队列是否已满。

示例 :
Leetcode 622. 设计循环队列

2.原题链接

Leetcode 622. 设计循环队列

3.思路分析

循环队列也是队列 ,自然拥有队列的特性 : 先进先出 , 但是循环队列它的优势表现在,如果队列满了之后,我们可以直接覆盖继续增加元素。

构造一个循环队列,可以采用两种不同形式的队列:顺序表和链表的方式去实现循环队列 ,这里我们采用顺序表实现

具体步骤 :
1 定义两个指针, front 表示头, tail 表示尾。创建数组 a, k 表示当前队列的长度 ,将这些变量分装成结构体

4.接口实现 :

Front

获取队首元素是相对比较简单的。直接返回当前 front 所在的元素即可。


int myCircularQueueFront(MyCircularQueue* obj) 
{if( myCircularQueueIsEmpty(obj)==true)return -1 ;else return obj->a[obj->front]; ;
}

Rear

拿到obj->rear-1 的元素

Leetcode 622. 设计循环队列

Leetcode 622. 设计循环队列

int myCircularQueueRear(MyCircularQueue* obj) 
{if( myCircularQueueIsEmpty(obj)==true)return -1 ;else {//return obj->a[ (obj->rear-1+obj->k+1)  % (obj->k+1) ]; int x = obj->rear == 0 ? obj->k : obj->rear-1 ; assert( x < obj->k+1) ;return obj->a[x];}}

enQueue(value):


bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)  //入队
{//队列已满 if(myCircularQueueIsFull(obj))return false ;//队列未满 obj->a[obj->rear++] = value;obj->rear  %= obj->k+1 ;return true ;
}

deQueue():

如果不取模 ,front可能越界 , 走到数组下标k+1的位置 ,所以我们取模可以让front绕回去

bool myCircularQueueDeQueue(MyCircularQueue* obj) //出队 
{ //空队列 if( myCircularQueueIsEmpty(obj)==true)return false;obj->front ++ ;obj->front %=( obj->k+1); //如果不取模 ,front可能越界 , 走到数组下标k+1的位置 ,所以我们取模可以让front绕回去return true ; }

isEmpty(): 检查循环队列是否为空

假设 k == 4 , 但是需要开辟了 k+1 个空间 ,也就是5个空间
当前队列的长度是k ,为什么要多开辟一个空间 ?

如果不多开辟一个空间 ,如下图 :
Leetcode 622. 设计循环队列

如果没有多开辟一个空间 , 就会发现无法判断循环队列是否为空

为了解决上述问题 , 我们选择多开辟一个空间便与判断循环队列是否为空, 如下图 :
Leetcode 622. 设计循环队列

Leetcode 622. 设计循环队列

bool myCircularQueueIsEmpty(MyCircularQueue* obj) 
{return obj->front == obj->rear ;
}

isFull():

bool myCircularQueueIsFull(MyCircularQueue* obj)
{return  (obj->rear + 1) % (obj->k + 1) == obj->front;}

如果不取模 ,rear可能越界 , 走到数组下标k+1的位置 ,所以我们取模可以让rear绕回去
Leetcode 622. 设计循环队列

myCircularQueueFree

void myCircularQueueFree(MyCircularQueue* obj){free( obj->a);free(obj) ;}

5.代码实现

typedef struct{   int k ; int *a ;int front ; int rear ; } MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k){// 顺序表 MyCircularQueue*obj = (MyCircularQueue*)malloc ( sizeof( MyCircularQueue));obj->rear =obj->front = 0 ;obj->k = k ;obj->a = (int*)malloc (sizeof( int) *(k+1)) ; //多开辟一个空间 ,好判断队列是否为空return obj ;  }
bool myCircularQueueIsEmpty(MyCircularQueue* obj) 
{return obj->front == obj->rear ;
}bool myCircularQueueIsFull(MyCircularQueue* obj){return  (obj->rear + 1) % (obj->k + 1) == obj->front;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)  //入队
{//队列已满 if(myCircularQueueIsFull(obj))return false ;//队列未满 obj->a[obj->rear++] = value;obj->rear  %= obj->k+1 ;return true ;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) //出队 
{ //空队列 if( myCircularQueueIsEmpty(obj)==true)return false;obj->front ++ ;obj->front %=( obj->k+1); //如果不取模 ,front可能越界 , 走到数组下标k+1的位置 ,所以我们取模可以让front绕回去return true ; }int myCircularQueueFront(MyCircularQueue* obj) 
{if( myCircularQueueIsEmpty(obj)==true)return -1 ;else return obj->a[obj->front]; ;
}int myCircularQueueRear(MyCircularQueue* obj) 
{if( myCircularQueueIsEmpty(obj)==true)return -1 ;else {//return obj->a[ (obj->rear-1+obj->k+1)  % (obj->k+1) ]; int x = obj->rear == 0 ? obj->k : obj->rear-1 ; assert( x < obj->k+1) ;return obj->a[x];}}void myCircularQueueFree(MyCircularQueue* obj){free( obj->a);free(obj) ;}

Leetcode 622. 设计循环队列
如果你觉得这篇文章对你有帮助,不妨动动手指给点赞收藏加转发,给鄃鳕一个大大的关注
你们的每一次支持都将转化为我前进的动力!!