您现在的位置是:首页 >其他 >Leetcode 622. 设计循环队列网站首页其他

Leetcode 622. 设计循环队列

鄃鳕 2023-05-28 16:00:02
简介Leetcode 622. 设计循环队列

1.题目描述

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

需要实现的接口:

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

示例 :
在这里插入图片描述

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 的元素

在这里插入图片描述

在这里插入图片描述

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 ,为什么要多开辟一个空间 ?

如果不多开辟一个空间 ,如下图 :
在这里插入图片描述

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

为了解决上述问题 , 我们选择多开辟一个空间便与判断循环队列是否为空, 如下图 :
在这里插入图片描述

在这里插入图片描述

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绕回去
在这里插入图片描述

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) ;

}

在这里插入图片描述
如果你觉得这篇文章对你有帮助,不妨动动手指给点赞收藏加转发,给鄃鳕一个大大的关注
你们的每一次支持都将转化为我前进的动力!!

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。