目录
队列的概念
队列:有特殊限制的线性表,只可以在表的前端进行删除操作,表的后端进行插入操作。
队列:先进先出表头删除,表尾插入(排队买饭)
队列实现
add/offer---队尾添加元素
public static void main(String[] args) {
Queue<Integer> queue = new LinkedList<>();
//LinkedList实现了Queue接口,发生了整型提升,queue可以调用Queue接口的方法
queue.add(1);//添加元素
queue.offer(2);//添加元素
System.out.println(queue);
}
peek/element---获取队头元素
public static void main(String[] args) {
Queue<Integer> queue = new LinkedList<>();
//LinkedList实现了Queue接口,发生了整型提升,queue可以调用Queue接口的方法
queue.add(1);//添加元素
queue.offer(2);//添加元素
System.out.println(queue);
System.out.println(queue.peek());
System.out.println(queue.element());
System.out.println(queue);
}
poll/remove---删除队头元素
public static void main(String[] args) {
Queue<Integer> queue = new LinkedList<>();
//LinkedList实现了Queue接口,发生了整型提升,queue可以调用Queue接口的方法
queue.add(1);//添加元素
queue.offer(2);//添加元素
System.out.println(queue);
System.out.println(queue.peek());
System.out.println(queue.element());
System.out.println(queue);
queue.poll();//删除队头元素
System.out.println(queue);
queue.remove();//删除队头元素
System.out.println(queue);
}
队列的模拟实现
使用双向链表来实现
LinkedList底层是一个双向链表,而LinkedList类是Queue接口的实现类
class Node{
int val;
Node prev;
Node next;
public Node(int val, Node prev, Node next) {
this.val = val;
this.prev = prev;
this.next = next;
}
}
public class MyIinkedQueue {
static Node head = null, tail = null;
public static void main(String[] args) {
add(1);
print();
remove();
}
public static void add(int val) {//队尾添加元素---尾插法
Node newnode = new Node(val, tail, null);
if (head == null) {
head = tail = newnode;
} else {
tail.next = newnode;
tail = newnode;
}
}
public static void remove() {//队头删除元素
if (head == null) {
throw new RuntimeException("删除的时候,队列空");
}
if (head.next == null) {
head = tail = null;
} else {
head.next.prev = null;
head = head.next;
}
}
public static int peek(){
if (head == null) {
throw new RuntimeException("获取元素的时候,队列空");
}else {
return head.val;
}
}
public static void print(){
Node p=head;
while(p!=null){
System.out.print(p.val+" ");
p=p.next;
}
System.out.println();
}
}
使用数组来实现---循环队列
使用循环队列的冲突:队列空和满的区分
解决办法:
(rear -front + MAXSIZE)%MAXSIZE; 长度
((rear+1)%MAXSIZE ==front)队满
if(rear ==front) ;队空
使用uesdsize
class MyCircularQueue {
int front=0;
int []elem;
int usedize=0;
int tail=0;
public MyCircularQueue(int k) {
this.elem=new int[k];
}
public boolean enQueue(int value) {
if(isFull() )
return false;
elem[tail]=value;
tail=(tail+1)%elem.length;
usedize++;
return true;
}
public boolean deQueue() {
if(isEmpty() )
return false;
front=(front+1)%elem.length;
usedize--;
return true;
}
public int Front() {
if(isEmpty() )
return -1;
return elem[front];
}
public int Rear() {
if(isEmpty())
return -1;
if(tail==0)
return elem[elem.length-1];
return elem[tail-1];
}
public boolean isEmpty() {
if(0==usedize)
return true;
return false;
}
public boolean isFull() {
if(elem.length==usedize)
return true;
return false;
}
}
减少一个空间
public int front, tail;
int[] elem;
public MyArrayQueue(int k) {
this.elem = new int[k];
}
public boolean enQueue(int value) {
if (isFull())
return false;
elem[tail] = value;
tail = (tail + 1) % elem.length;
return true;
}
public boolean deQueue() {
if (isEmpty())
return false;
front = (front + 1) % elem.length;
return true;
}
public int Front() {
if (isEmpty())
return -1;
return elem[front];
}
public int Rear() {
if (isEmpty())
return -1;
if (tail == 0)
return elem[elem.length - 1];
return elem[tail - 1];//tail=0时,越界
}
public boolean isEmpty() {
if (tail == front)
return true;
return false;
}
public boolean isFull() {
if ((tail + 1) % elem.length == front)
return true;
return false;
}
public int uedsize() {
return( (tail-front+elem.length)%elem.length);
}
双端队列
双端队列是在对头和队尾都可以进行插入和删除的队列
public static void main(String[] args) {
Deque<Integer> deque = new LinkedList<>();
deque.offer(1);
deque.add(3);
System.out.println(deque);
}
这两个方法都可以添加元素,有什么区别呢?
add会抛出异常,offer不会
232. 用栈实现队列https://leetcode-cn.com/problems/implement-queue-using-stacks/
class MyQueue {
Stack<Integer> stack1=new Stack<>();
Stack<Integer> stack2=new Stack<>();
public MyQueue() {
}
public void push(int x) {
stack1.push(x);
}
public int pop(){
if(stack2.isEmpty()){
while(!stack1.isEmpty()){
int x=stack1.peek();
stack2.push(x);
stack1.pop();
}
}
int x=stack2.peek();
stack2.pop();
return x;
}
public int peek() {
if(stack2.isEmpty()){
while(!stack1.isEmpty()){
int x=stack1.peek();
stack2.push(x);
stack1.pop();
}
}
int x=stack2.peek();
return x;
}
public boolean empty() {
if(stack2.isEmpty()==true&&stack1.isEmpty()==true)
return true;
return false;
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/
225. 用队列实现栈https://leetcode-cn.com/problems/implement-stack-using-queues/
class MyStack {
Queue <Integer> queue=new LinkedList<>();
public MyStack() {
}
public void push(int x) {
int sz=queue.size();
queue.add(x);
while(sz-->=1){
int y=queue.peek();
queue.remove();
queue.add(y);
}
}
public int pop() {
int y=queue.peek();
queue.remove();
return y;
}
public int top() {
int y=queue.peek();
return y;
}
public boolean empty() {
return queue.isEmpty();
}
}
/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* boolean param_4 = obj.empty();
*/