构造队列及循环队列(Java实现)
队列
定义
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First
In First Out) 入队列:进行插入操作的一端称为队尾(Tail/Rear) 出队列:进行删除操作的一端称为队头
(Head/Front)
代码实现
- 链表实现
public class Queue {
public static class Node{
int val;
Node next;
public Node(int val) {
this.val = val;
this.next = null;
}
}
private Node front;
private Node rear;
private int size;
public Queue() {
front = rear = null;
this.size = 0;
}
public void offer(int val) {
//尾插
Node node = new Node(val);
if (front == null){
front = rear = node;
}else{
rear.next = node;
rear = rear.next;
}
size++;
}
public void poll(){
//头删
if (front == null){
return;
}
front = front.next;
//队列中只有一个节点,更新尾节点
if (front == null){
rear = null;
}
size--;
}
public int peek(){
if (size == 0){
throw new RuntimeException("队列为空");
}
return front.val;
}
public int getSize(){
return size;
}
public boolean isEmpty(){
return size == 0;
}
}
-
栈实现
import java.util.EmptyStackException; import java.util.Stack; /** * 借助两个栈来实现队列 * pushStack 只负责入队列 * popStack 只负责出队列 * 进行出队列操作时 * 当popStack为空时 : 将pushStack中的元素全部出栈加入到popStack中 根据栈后进先出原则 * 此时最先进入的元素存储在popStack栈顶,直接出栈即可 * 当popStack不为空时 : 直接出栈 */ class MyQueue { Stack<Integer> pushStack; Stack<Integer> popStack; public MyQueue() { pushStack = new Stack<>(); popStack = new Stack<>(); } public void push(int val) { pushStack.add(val); } public int pop() { if (popStack.isEmpty()){ while (!pushStack.isEmpty()){ popStack.add(pushStack.pop()); } } return popStack.pop(); } public int peek() { if (popStack.isEmpty()){ while (!pushStack.isEmpty()){ popStack.add(pushStack.pop()); } } return popStack.peek(); } public boolean empty() { return popStack.isEmpty() && pushStack.isEmpty(); } }
题目链接 :https://leetcode-cn.com/problems/implement-queue-using-stacks/
循环队列
定义
设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。
代码实现
顺序表实现
class MyCircularQueue{
private int[] array;
//front: 队头元素的位置
private int front;
//rear: 队尾元素的下一个位置
private int rear;
//size : 队列元素个数
private int size;
public MyCircularQueue(int k) {
array = new int[k];
front = 0;
rear = 0;
size = 0;
}
public boolean enQueue(int value) {
//判断队列是否已满
if (isFull()){
return false;
}
//尾插
array[rear++] = value;
//更新位置
rear = rear % array.length;
//更新元素个数
size++;
return true;
}
public boolean deQueue() {
//判断队列是否为空
if (isEmpty()){
return false;
}
头删,向后移动队头的位置
front++;
front = front % array.length;
size--;
return true;
}
public int Front() {
if (isEmpty()){
return -1;
}
return array[front];
}
public int Rear() {
if (isEmpty()){
return -1;
}
// rear在 0 位置 ,且不为空 ,队尾下标为 array.length - 1
if (rear == 0){
return array[array.length - 1];
}
//队尾元素在 rear-1的位置
return array[rear - 1];
}
public boolean isEmpty() {
return size == 0;
}
public boolean isFull() {
return size == array.length;
}
}
题目链接 :https://leetcode-cn.com/problems/design-circular-queue/