首页 > 其他分享 >leetcode622. 设计循环队列

leetcode622. 设计循环队列

时间:2022-11-14 10:31:31浏览次数:57  
标签:返回 leetcode622 obj 队列 MyCircularQueue int 循环 rear

题目

设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。 循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。 你的实现应该支持如下操作: MyCircularQueue(k): 构造器,设置队列长度为 k 。 Front: 从队首获取元素。如果队列为空,返回 -1 。 Rear: 获取队尾元素。如果队列为空,返回 -1 。 enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。 deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。 isEmpty(): 检查循环队列是否为空。 isFull(): 检查循环队列是否已满。

示例: MyCircularQueue circularQueue = new MyCircularQueue(3); // 设置长度为 3 circularQueue.enQueue(1);  // 返回 true circularQueue.enQueue(2);  // 返回 true circularQueue.enQueue(3);  // 返回 true circularQueue.enQueue(4);  // 返回 false,队列已满 circularQueue.Rear();  // 返回 3 circularQueue.isFull();  // 返回 true circularQueue.deQueue();  // 返回 true circularQueue.enQueue(4);  // 返回 true circularQueue.Rear();  // 返回 4

# 代码



typedef struct {
  int* a;
  int front;
  int rear;
  int k;
} MyCircularQueue;
bool myCircularQueueIsEmpty(MyCircularQueue* obj);//定义
bool myCircularQueueIsFull(MyCircularQueue* obj) ;
MyCircularQueue* myCircularQueueCreate(int k) {
   MyCircularQueue*obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
   obj->a=(int*)malloc(sizeof(int)*(k+1));
   obj->front=obj->rear=0;
   obj->k=k;
   return obj;
}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
  if( myCircularQueueIsFull(obj))//入队 如果满了就不用入队了
  {
      return false;
  }
  obj->a[obj->rear++]=value;
  obj->rear%=(obj->k+1);//有可能处于最后一个位置 若想要返回第一个位置%k+1
  return true;

}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
     if(myCircularQueueIsEmpty(obj))//出队 若没有数据出队 就返回false
     {
         return false;
     }
     obj->front++;  //数组中 front++ 就代表消除
     obj->front%=(obj->k+1); //有可能处于最后一个位置 若想要返回第一个位置%k+1
     return true;
}

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

int myCircularQueueRear(MyCircularQueue* obj) {
  if(myCircularQueueIsEmpty(obj))
  {
      return -1;
  }
  int rear=obj->rear==0?obj->k:obj->rear-1;//若rear为下标为0的位置处,就要返回到-1处 会报错
   return obj->a[rear]; //实际上是返回到 下标为k的位置处
}

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

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    return (obj->rear+1)%(obj->k+1)==obj->front;//多开辟了一块空间 就是为了当入了k个数据后
    //rear++ 处于 第k+1个位置处 ,%k+1正好为 下返回到标为0的位置处
}

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

/**
 * Your MyCircularQueue struct will be instantiated and called as such:
 * MyCircularQueue* obj = myCircularQueueCreate(k);
 * bool param_1 = myCircularQueueEnQueue(obj, value);
 
 * bool param_2 = myCircularQueueDeQueue(obj);
 
 * int param_3 = myCircularQueueFront(obj);
 
 * int param_4 = myCircularQueueRear(obj);
 
 * bool param_5 = myCircularQueueIsEmpty(obj);
 
 * bool param_6 = myCircularQueueIsFull(obj);
 
 * myCircularQueueFree(obj);
*/

解析

1.队列为空时

当为空时 rear==front image.png

2.队列满的情况

  • 判断满的情况

  • 当k=4,k+1=5时,rear++
  • image.png
  • 因为循环队列,所以应返回到 下标为0处
  • rear==4, (rear+1)%(k+1)=5%5=0

3.入队列

  • 正常来说 入一个数据后,rear++,但当处于以下位置时就需要考虑到循环返回到下标为0位置的情况
  • image.png
  • 此时 的 rear++ ,rear=5 ,rear%(k+1)=5%5=0

4. 出队列

出队列时,每次front++,但当处于以下位置时需要考虑到循环返回到下标为0位置的情况

image.png

此时 的 front++ ,front=5 ,front%(k+1)=5%5=0

5.出队尾数据

因为每次 rear入一个数据后,都会++,所以需要找 obj->a[obj->rear-1] 但是需要考虑到以下位置 image.png

  • 当rear处于下标为0的位置,rear-1为下标为-1的位置就会报错
  • rear这里的位置是 在4的位置后 ,rear++后,%k+1得来的,而4的位置正好为k所在所以判断下
  • int rear= rear==0?k:rear-1;

标签:返回,leetcode622,obj,队列,MyCircularQueue,int,循环,rear
From: https://blog.51cto.com/u_15787387/5848511

相关文章

  • Day10.1:while循环结构
    while循环结构while循环while循环结构是最基本的循环,他的结构为:while(布尔表达式){//循环的内容}只有当布尔表达式的值为true时,开始循环我们一般需要的是有限......
  • 分支和循环(2)
    #include<stdio.h>intmain(){//EOF-endoffile文件结束标志intch=0;while((ch=getchar())!=EOF){putchar(ch);}return0;}scanf和getchar都是输......
  • 《Linux内核设计与实现》内核数据结构6.2队列 P78-81
    队列与堆栈队列只允许在队列的前端(front,队头)进行删除操作,而在队列的后端(rear,队尾)进行插入操作。当队列中没有元素时,即front=rear,称为空队列。在队列中插入一个队列元素称......
  • 队列链表实现
    队列没有元素是FrontRear指向NULL 只有一个元素时都指向那一个元素因为既是第一个元素也是最后一个元素即队头队尾 Front指向第一个元素Rear指向最后一个元素#......
  • 单调栈/单调队列
    单调栈/单调队列典型力扣题目239:滑动窗口最大值双端队列,队列存放元素按一定规则有序//双端队列Deque:LinkedList,ArrayDeque,LinkedDeque,LinkedBlockingDequeDequ......
  • 循环队列顺序表实现
    #include<stdlib.h>#include<stdio.h>#include<stdbool.h>#include<math.h>/**循环队列的顺序存储实现队列头在队列第一个元素前不指向元素队列尾是指向队......
  • 聊聊消息队列(MQ)那些事
    每年的双十一期间,各大电商平台流量暴增,同时,电商平台系统的负载压力也会很大。譬如订单支付的场景,每个订单支付成功后,服务器可能要完成扣减积分、扣减优惠券、扣减商品库存......
  • 循环更新
    第三节循环语句1.基础知识:whiledowhileforif是判断一次执行后面的语句,while是每次成立执行循环语句中的语句if(a%2)与if(a%2==0)i区别f(a%2)是对A%2的结果......
  • JavaScript中的几种for循环效率对比
    JavaScript(下文简称JS)中最常用的数据结构有两种,即数组(下文用Array表示)和对象(下文用Object表示)。须要注意的是,本质上,数组也是一种对象,只不过是特殊的对象。遍历Array和Obje......
  • python的while循环
    语法while条件:#条件成立,循环执行的代码一#条件成立,循环执行的代码二#条件成立,循环执行的代码三#条件成立,循环执行的代码四#.......如......