一.概念
只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的特点。进行插入操作的一端称为队尾,进行删除操作的一端称为队头
二.队列的使用
Queue是个接口,底层是通过链表实现的
public class Main {
public static void main(String[] args) {
Queue<Integer> q = new LinkedList<>();
q.offer(1);
q.offer(2);
q.offer(3); //从队尾入队列
System.out.println(q.size()); //获取队列中有效元素个数
System.out.println(q.peek()); //从队头出队列,并将删除的元素返回
System.out.println(q.poll());//从队头出队列,并将删除的元素返回
if (q.isEmpty()){
System.out.println("队列空");
}else {
System.out.println(q.size());
}
}
}
三.队列模拟实现
四.循环队列
1.如何让下标回到0
2.如何区分空与满
1.通过size属性记录
2.保留一个位置
3.使用标记
3.设计循环队列
class MyCircularQueue {
public int[] elem;
public int front; //队头下标
public int rear; //队尾下标
public MyCircularQueue(int k) {
elem = new int[k+1]; 因为要浪费一个空间判断是否满,所以数组实际大小要k+1
rear = front = 0;
}
public boolean enQueue(int value) {
if(!isFull()){
elem[rear] = value;
rear = (rear+1)%elem.length;
return true;
}
return false;
}
public boolean deQueue() {
if(!isEmpty()){
front = (front+1)%elem.length;
return true;
}
return false;
}
public int Front() {
if(isEmpty()){
return -1;
}
return elem[front];
}
public int Rear() {
if(isEmpty()){
return -1;
}
return elem[(rear - 1 + elem.length) % elem.length];
}
public boolean isEmpty() {
return front == rear;
}
public boolean isFull() {
return (rear+1)%elem.length == front;
}
}
五.双端队列(Deque)
双端队列是指允许两端都可以进行入队和出队操作的队列。
Deque是一个接口,使用时必须创建LinkedList的对象。
Deque接口使用较多,栈和队列均可以使用该接口
Deque<Integer> stack = new ArrayDeque<>();//双端队列的线性实现
Deque<Integer> queue = new LinkedList<>();//双端队列的链式实现
六.题目
1.用队列实现栈
class MyStack {
Queue<Integer> q1 ;
Queue<Integer> q2 ;
public MyStack() {
q1 = new LinkedList<>();
q2 = new LinkedList<>();
}
public void push(int x) {
if (!q2.isEmpty()){
q2.offer(x);
}else {
q1.offer(x);
}
}
public int pop() {
if (empty()){
return -1;
}else if (q1.isEmpty()){
int size = q2.size();
for (int i = 0; i< size-1; i++){
q1.offer(q2.poll());
}
return q2.poll();
}else{
int size = q1.size();
for (int i = 0; i< size-1; i++){
q2.offer(q1.poll());
}
return q1.poll();
}
}
public int top() {
int tmp = 0;
if (empty()){
return -1;
}else if (q1.isEmpty()){
int size = q2.size();
for (int i = 0; i< size; i++){
tmp = q2.poll();
q1.offer(tmp);
}
return tmp;
}else{
int size = q1.size();
for (int i = 0; i< size; i++){
tmp = q1.poll();
q2.offer(tmp);
}
return tmp;
}
}
public boolean empty() {
return q1.isEmpty() && q2.isEmpty();
}
}
2.用栈实现队列
class MyQueue {
Stack<Integer>q1;
Stack<Integer>q2;
public MyQueue() {
q1 = new Stack<>();
q2 = new Stack<>();
}
public void push(int x) {
q1.push(x);
}
public int pop() {
if (!q2.empty()){
return q2.pop();
}else if (empty()){
return -1;
}else {
int size = q1.size();
for (int j = 0; j < size; j++) {
q2.push(q1.pop());
}
return q2.pop();
}
}
public int peek() {
if (!q2.empty()){
return q2.peek();
}else if (empty()){
return -1;
}else {
int size = q1.size();
for (int j = 0; j < size; j++) {
q2.push(q1.pop());
}
return q2.peek();
}
}
public boolean empty() {
return q1.empty() && q2.empty();
}
}