前言
本博客是对队列与栈做相关练习时所做笔记,主要内容来源队列与栈。
队列
普通队列
-
特点:先入先出。从队尾入队,从队首出队。
-
实现:可使用动态数组来实现,并用一个指针指向数组的头部,即记录头部的位置。入队会向队列追加一个新元素,而出队会删除第一个元素。
class MyQueue { // 动态数组存储元素 private List<Integer> data; // 用一个指针指向头部 private int p_start; public MyQueue() { data = new ArrayList<Integer>(); p_start = 0; } //入队,插入成功返回true public boolean enQueue(int x) { data.add(x); return true; }; //出队,同时指向头部的指针后移一位 public boolean deQueue() { if (isEmpty() == true) { return false; } p_start++; return true; } //获取队首元素 public int Front() { return data.get(p_start); } //判断队列是否为空 public boolean isEmpty() { return p_start >= data.size(); } };
可见,上述操作虽然实现简单,但随着头部指针的移动,将会浪费大量的空间。而循环队列可以解决这个问题。
循环队列
-
循环队列使用固定大小的数组,并使用一个指针(设为
head
)指向队首,一个指针(设为tail
)指向队尾元素的下一个位置。 -
入队时移动
tail
,即tail = (tail+1) % queue.length;
出队时移动
head
,即head = (head+1) % queue.length;
-
队列空时:
head == tail;
队列满时:
(tail+1) % queue.length == head;
622.设计循环队列
-
题目描述:设计一个循环队列,其支持以下操作:
MyCircularQueue(k): 构造器,设置队列长度为 k 。
Front: 从队首获取元素。如果队列为空,返回 -1 。
Rear: 获取队尾元素。如果队列为空,返回 -1 。
enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
isEmpty(): 检查循环队列是否为空。
isFull(): 检查循环队列是否已满。 -
分析:
使用一个指针指向队首,一个指针指向队尾元素的下一个位置。这样做可更加容易实现一些操作。
-
代码:
class MyCircularQueue { private int[] queue; //head指向头部,tail指向队尾元素的下一个位置 private int head, tail; //初始化一个长度为k的队列 public MyCircularQueue(int k) { queue = new int[k+1]; head = 0; tail = 0; } /** Insert an element into the circular queue. Return true if the operation is successful. */ public boolean enQueue(int value) { if(isFull()) return false; queue[tail] = value; tail = (tail+1) % queue.length; return true; } /** Delete an element from the circular queue. Return true if the operation is successful. */ public boolean deQueue() { if(isEmpty()) return false; head = (head+1) % queue.length; return true; } /** Get the front item from the queue. */ public int Front() { if(isEmpty()) { return -1; } return queue[head]; } /** Get the last item from the queue. */ public int Rear() { if(isEmpty(