设计循环队列-------------

设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。

循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。

你的实现应该支持如下操作:

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

需要解决的问题:

1.如何判断循环队列是否为空?

在非空情况下,rear和front不会相遇(在同一个位置),所以当rear == front时,此循环对列为空,实例图如下:

2.怎么判断一个循环队列是满的?

2.1 定义一个usedSize(有效元素个数),usedSize==0时,即为空。

2.2可以通过维护一个 isFull 布尔值和一个 size 属性:

class CircularQueue {
    private int[] queue;
    private int front;
    private int rear;
    private int capacity;
    private int size; 
    private boolean isFull;

    public CircularQueue(int capacity) {
        this.capacity = capacity;
        this.queue = new int[capacity];
        this.front = 0;
        this.rear = -1;
        this.size = 0;
        this.isFull = false; // 初始化为空
    }

    public boolean isEmpty() {
        return size == 0; 
    }

    public boolean isFull() {
        return size == capacity; // 或者直接返回 isFull
    }

2.3浪费一个空间,通过rear的下一个元素是否为front来判断是否已满

这里的判满方法我们用第三种。

2.4: rear或front下标从7 位置 到0位置该怎么处理?如果直接rear+1,rear =8,不能重新进入循环,超出范围,这时我们就要借助一个公式:rear/front = (rear+1)%length(数组长度)。

步骤:

1.循环队列结构的创建:

int front(队头)

int rear(队尾)

int[ ] elem  //保存整数的数组

1.2循环队列构造方法的创建:

创建一个容纳k+1个数量的数组elem();

具体代码如下:

class MyCircularQueue {
            public int rear;
            public int front;
            public int[] elem;
    public MyCircularQueue(int k) {
               elem = new int[k+1];
    }
    

2 入队方法(enQueue)的实现:

在元素入队(插入)之前,先判断队列是否已满(布尔方法 isFull(判断条件:rear的下一个元素是否为front)),如果已经满,返回false.

队列未满,进行插入:将值value插入rear位置,同时rear更新至下一个位置,更新完毕后返回true即可。

具体代码如下:

public boolean enQueue(int value) {
               if(isFull()){
                return false;
               }else{
                elem[rear] = value;
                rear = (rear+1)%elem.length; //指向下一个节点
                return true;
               }

    }

3.出队方法的实现:

进行出队操作之前,判断队列是否为空,若为空,返回false,

若不为空,通过front = (front+1)% elem.length 更新front位置指针,并返回true值

具体代码如下:

public boolean deQueue() {
          if(isEmpty()){
            return false;
          }else{
            front = (front+1)%elem.length; //更新front节点
           return true;
          }
    }

4.Front方法的实现:(获取队头元素)

获取队头元素之前,判断队列是否为空,为空,返回-1(int 方法),

否则,返回位于front位置的元素。具体代码如下:

public int Front() {
          //获取队头元素
          if(isEmpty()){
            return -1;
          }else{
           return elem[front];
          }

    }

5. Rear(获取队尾元素) 方法的实现:

先判断队列是否尾空,为空,返回false,

不为空的话,由于rear位置插入新值后都会往后再走一步,要获取队尾的元素,需要将创建一个整形index来接收 rear-1 ,再通过elem数组返回index位置的值。但这里有一个特殊情况:

当rear == 0 时,rear-1 = -1,此时实际的队尾位置在7位置处:

此时需总长度-1,得到的即为队尾位置 ,具体代码如下:

 public int Rear() {
   if(isEmpty()){
     return -1;
   }else{
       int index =  (rear == 0)?  elem.length-1 : rear-1;
       return elem[index];
   }
    }
    

最后,判断队列是否为空依据:rear 是否 == front

         判断队列是否已满的依据:(rear+1)%elem.length 是否 == front 

到这里,题目基本上已经完成。

喜欢的老贴们点个赞吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值