Java数据结构-队列

队列是一种先进先出 的运算受限的线性结构,在一端进入入队插入 操作,另一端进行出队删除操作。

代码实现

接口定义

java 复制代码
public interface Queue<E> {  
  
    /**  
     * 入队  
     *  
     * @param e 离队  
     */  
    void enqueue(E e);  
  
    /**  
     * 离队  
     *  
     * @return 返回出队元素  
     */  
    E dequeue();  
  
    /**  
     * 返回队列是否为空  
     *  
     * @return 返回结果  
     */  
    boolean isEmpty();  
  
  
    /**  
     * 读取对头  
     *  
     * @return 返回元素  
     */  
    E getHead();  
  
    /**  
     * 检查元素是否为空指针  
     * @param e 元素  
     */  
    default void check(E e) {  
        if (e == null) {  
            throw new NullPointerException();  
        }    }}

顺序表

队列的实现的难点在于顺序表,由于做循环列表,所以指针 frontrear 都设置为0

从该图可以看出,仅仅靠front==rear只能说明队列为空或者是满队列

所以通过判断0号数据或数组最后一位元素为空,来判断队列为空。

而满队列有两种情况:

  1. rear + (elementData.length - front) == elementData.length,如front=1,rear=1,则1+(7-1)=7。
  2. front == 0 && rear == elementData.length,如[0,1,2,3,4,5,6],front = 0, rear = 7,则:7+(7-0)= 14,不满足条件1。所以需要条件2

在实现的队列拓展时候,将front重置为0,rear重置为旧数组的长度

java 复制代码
package com.silvergravel.structure;  
  
import java.util.Arrays;  
import java.util.NoSuchElementException;  
  
/**  
 * @author DawnStar  
 * @since 2025/8/3  
 */
 public class QueueSequence<E> implements Queue<E> {  
  
    protected Object[] elementData;  
  
    private int front = 0, rear = 0;  
  
  
    public QueueSequence(int initialCapacity) {  
        if (initialCapacity <= 0) {  
            this.elementData = new Object[10];  
            return;  
        }        this.elementData = new Object[initialCapacity];  
    }  
    @Override  
    public void enqueue(E e) {  
        check(e);  
        // 这里实现二  
//        if (isEmpty()) {  
//            // 队空重置  
//            rear = 0;  
//            front = 0;  
//            elementData[rear] = e;  
//            rear++;  
//            return;  
//        }  
        // [0,1,2,3,4,5,6]        // 如果 front = 3,rear =3 3+(7-3) =7        // 如果 front = 2,rear =2 2+(7-2) =7        // front = 0 ,rear =7  7+(7-0) = 14  
              boolean b = (rear + (elementData.length - front) == elementData.length) || (front == 0 && rear == elementData.length);  
        // 判断队列不为空且长度为7  
        if (b && !isEmpty()) {  
//        if (b) {  
            // 如果使用上述的注释实现二,那么 则不用使用 !isEmpty()            grow();  
        } else if (rear == elementData.length) {  
            //  [null,null,2,3,4,5,6]  
            rear = 0;  
        }        elementData[rear] = e;  
        rear++;  
  
    }  
    @Override  
    @SuppressWarnings("unchecked")  
    public E dequeue() {  
        if (isEmpty()) {  
            throw new NoSuchElementException();  
        }        if (front == elementData.length) {  
            front = 0;  
            E elementDatum = (E) elementData[front];  
            elementData[front] = null;  
            return elementDatum;  
        } else {  
            E elementDatum = (E) elementData[front];  
            elementData[front] = null;  
            front++;  
            return elementDatum;  
        }    }  
    @Override  
    public boolean isEmpty() {  
        // rear == front 只能判断队空队满,但是不能判断是其中哪一种情况,所以再加上通过第一个元素为空来判断  
        return rear == front && elementData[0] == null;  
    }  
    @Override  
    @SuppressWarnings("unchecked")  
    public E getHead() {  
        if (front == elementData.length) {  
            return (E) elementData[0];  
        }        return (E) elementData[front];  
    }  
    private void grow() {  
        // 当前值的1.5倍  
        int newSize = (elementData.length + 1) / 2 * 3;  
  
        if (front < rear) {  
            elementData = Arrays.copyOf(elementData, newSize);  
            return;  
        }        final Object[] oldData = elementData;  
        elementData = new Object[newSize];  
        int length = oldData.length - front;  
        System.arraycopy(oldData, front, elementData, 0, length);  
        System.arraycopy(oldData, 0, elementData, length, rear);  
        // 重置指针数据  
        front = 0;  
        rear = oldData.length;  
    }  
    public int getFront() {  
        return front;  
    }  
    public int getRear() {  
        return rear;  
    }  
    public int size() {  
        return elementData.length;  
    }  
  
    @Override  
    public String toString() {  
        return "[" + String.join(",", Arrays.stream(elementData).map(String::valueOf).toList()) + "]";  
    }}

链表实现

java 复制代码
  
/**  
 * 尾插法  
 *  
 * @author DawnStar  
 * @since 2025/8/3  
 */
 public class QueueLink<E> implements Queue<E> {  
  
    protected Node<E> head;  
    protected Node<E> rear;  
  
    public QueueLink() {  
        this.rear = new Node<>(null, null);  
        this.head = new Node<>(null, this.rear);  
    }  
    @Override  
    public void enqueue(E e) {  
        check(e);  
        rear.element = e;  
        Node<E> node = new Node<>(null, null);  
        rear.next = node;  
        rear = node;  
    }  
    @Override  
    public E dequeue() {  
        Node<E> next = head.next;  
        check(next.element);  
        head.next = next.next;  
        return next.element;  
    }  
    @Override  
    public boolean isEmpty() {  
        return head.next.element == null;  
    }  
    @Override  
    public E getHead() {  
        E element = head.next.element;  
        check(element);  
        return element;  
    }  
    protected static class Node<E> {  
        private E element;  
        private Node<E> next;  
  
        public Node(E element, Node<E> next) {  
            this.element = element;  
            this.next = next;  
        }  
        public E getElement() {  
            return element;  
        }  
        public void setElement(E element) {  
            this.element = element;  
        }  
        public Node<E> getNext() {  
            return next;  
        }  
        public void setNext(Node<E> next) {  
            this.next = next;  
        }    }}

代码测试

java 复制代码
/**  
 * @author DawnStar  
 * @since 2025/8/3  
 */
 public class QueueTest {  
    public static void main(String[] args) {  
        System.out.println("=".repeat(30) + "队列顺序表实现" + "=".repeat(50));  
        QueueSequence<String> queue = new QueueSequence<>(2);  
        queue.enqueue("A");  
        queue.enqueue("B");  
        queue.enqueue("C");  
        System.out.println(queue.dequeue());  
        System.out.println(queue.dequeue());  
        System.out.println("当前front指针:" + queue.getFront());  
        System.out.println("当前尾指针:" + queue.getRear());  
        System.out.println("长度:" + queue.size());  
        queue.enqueue("D");  
        queue.enqueue("E");  
        System.out.println("当前front指针:" + queue.getFront());  
        System.out.println("当前尾指针:" + queue.getRear());  
        System.out.println("长度:" + queue.size());  
        System.out.println(queue);  
        // 数组拓展  
        queue.enqueue("F");  
        System.out.println("长度:" + queue.size());  
        System.out.println(queue);  
  
        System.out.println("=".repeat(30) + "队列链表实现" + "=".repeat(50));  
        Queue<Integer> linkQueue = new QueueLink<>();  
        Stream.of(1, 2, 3, 4, 5, 6).forEach(linkQueue::enqueue);  
        List<Integer> list = new ArrayList<>();  
  
        while (!linkQueue.isEmpty()) {  
            list.add(linkQueue.dequeue());  
        }        System.out.println(list.stream().map(String::valueOf).collect(Collectors.joining("、")));  
  
    }}
相关推荐
小明的小名叫小明14 分钟前
区块链技术原理(14)-以太坊数据结构
数据结构·区块链
pusue_the_sun15 分钟前
数据结构——栈和队列oj练习
c语言·数据结构·算法··队列
亲爱的马哥22 分钟前
重磅更新 | 填鸭表单TDuckX2.9发布!
java
Java中文社群23 分钟前
26届双非上岸记!快手之战~
java·后端·面试
whitepure28 分钟前
万字详解Java中的面向对象(二)——设计模式
java·设计模式
whitepure30 分钟前
万字详解Java中的面向对象(一)——设计原则
java·后端
2301_793086871 小时前
SpringCloud 02 服务治理 Nacos
java·spring boot·spring cloud
奶黄小甜包1 小时前
C语言零基础第18讲:自定义类型—结构体
c语言·数据结构·笔记·学习
想不明白的过度思考者1 小时前
数据结构(排序篇)——七大排序算法奇幻之旅:从扑克牌到百亿数据的魔法整理术
数据结构·算法·排序算法
回家路上绕了弯1 小时前
MySQL 详细使用指南:从入门到精通
java·mysql