【恋上数据结构】队列 Queue

本文介绍了如何用Java设计队列接口,通过栈模拟队列,探讨了双端队列(Deque)的接口设计,并详细讲解了循环队列的实现原理。适合理解数据结构和算法的开发者学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GItee持续更新
在这里插入图片描述

六、队列(Queue)

队列是一种特殊的线性表,只能在头尾两端进行操作。

先进先出

在这里插入图片描述

1.接口设计

队列中的方法总结:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vr06B7AI-1640843678132)(%E6%81%8B%E4%B8%8A%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84.assets/image-20211229165553123.png)]

优先使用双向链表,因为动态数组在头操作复杂度较高。

package 栈和队列;


import java.util.LinkedList;

/**
 * @ClassName: Queue
 * @Description: 队列
 * @author: wangz48
 * @date: 2021-12-29 16:26
 */
public class Queue<E> {
    private LinkedList<E> linkedList = new LinkedList();

    /**
     * 队列的长度
     * @return
     */
    public int size(){
       return linkedList.size();
    }

    /**
     * 判断是否为空
     * @return
     */
    public boolean isEmpty(){
        return linkedList.isEmpty();
    }

    /**
     * 尾插
     * @param element
     */
    public void offer(E element){
        linkedList.add(element);
    }

    /**
     * 头删
     */
    public E poll(){
       return linkedList.poll();
    }

    /**
     * 获取队头
     * @return
     */
    public E peek(){
        return linkedList.get(0);
    }
}

public class QueueTest {
    public static void main(String[] args) {
        Queue<Integer> queue = new Queue();
        queue.offer(99);
        queue.offer(88);
        queue.offer(77);
        System.out.println(queue.peek());
        while (!queue.isEmpty()){
            System.out.println(queue.poll());
        }
    }
}

2.练习-用栈来实现队列

请添加图片描述

思路:

  • 用两个栈来模拟队列、

请添加图片描述

  • 入队时,push到 S1中

  • 出队时

    如果S2为空,将S1中所有的元素弹出,push到S2中,S2弹出栈顶元素。

    如果S2不为空,S2弹出栈顶元素。

实现

class MyQueue {

   /**
     * 相当于对头的栈
     */
    private Stack<Integer> queueHead ;
    /**
     * 相当于队尾的栈
     */
    private Stack<Integer> queueTail ;
    public MyQueue() {
        queueHead = new Stack<>();
        queueTail = new Stack<>();
    }

    public void push(int x) {
        queueTail.push(x);
    }

    public int pop() {
        if (queueHead.empty()) {
            while (!queueTail.empty()) {
                Integer e = queueTail.pop();
                queueHead.push(e);
            }
        }
        return queueHead.pop();
    }

    public int peek() {
        if (queueHead.empty()) {
            while (!queueTail.empty()) {
                Integer e = queueTail.pop();
                queueHead.push(e);
            }
        }
        return queueHead.peek();
    }

    public boolean empty() {
        return queueHead.isEmpty() && queueTail.isEmpty();
    }
}

3.双端队列(Deque)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UwoUzLyY-1640843823779)(%E6%81%8B%E4%B8%8A%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84.assets/image-20211230112915358.png)]

接口设计

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FB6o7Yh1-1640843823780)(%E6%81%8B%E4%B8%8A%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84.assets/image-20211230112705429.png)]

Queue与Deque比较

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g0l8YulR-1640843823780)(%E6%81%8B%E4%B8%8A%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84.assets/image-20211230112816372.png)]

Stack与Deque比较

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M7H1xild-1640843823781)(%E6%81%8B%E4%B8%8A%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84.assets/image-20211230112900131.png)]

4.循环队列(Circle Queue)

我们可以建立一个数组和两个指针来模拟循环队列。另外还设置了一个用来计数的变量,记录数组中元素的个数,使得我们能够更加容易的去判断队列当前的状态,已满或者为空。

class MyCircularQueue {
    		int[] queue;
    		int size;//对列的容量
    		int front;//头指针
    		int rear;//尾指针
    		int E_num;//当前队列中元素的个数
    	    public MyCircularQueue(int k) {//初始化
    	    	this.queue=new int[k];
    	    	this.size=k;
    	    	this.front=-1;
    	    	this.rear=0;
    	    	this.E_num=0;
    	    }
    	    public boolean enQueue(int value) {//入队
    	    	if(E_num>=size) return false;
    	    	front=(front+1)%size;
    	    	queue[front]=value;
    	    	E_num++;
    	    	return true;
    	    }
    	    public boolean deQueue() {//出队
    	    	if(E_num==0) return false;
    	    	rear=(rear+1)%size;
    	    	E_num--;
    	    	return true;
    	    }
    	    public int Front() {//获取队头元素(当前所有元素中最先进入的元素)
    	    	if(E_num==0) return -1;
    	    	return queue[rear];
    	    }
    	    
    	    public int Rear() {//获取队尾元素(当前所有元素中最后入队的元素)
    	    	if(E_num==0) return -1;
    	    	return queue[front];
    	    }
    	    public boolean isEmpty() {//判断队空
    	    	if(E_num==0) return true;
    	    	return false;
    	    }
    	    public boolean isFull() {//判断队是否已满
    	    	if(E_num==size) return true;
    	    	return false;
    	    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

结构化思维wz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值