队列

队列是一种特殊的线性表,是一种先进先出(FIFO)的数据结构。它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。

队列可以使用数组和链表这两种方式来实现,源码如下

定义队列行为接口InterfaceQueue.java

队列的几种行为都是确定的,不同的是底层如何实现,所以首先定义队列行为接口。声明最大队列长度为10,如果队列中元素超过了10则拒绝入队。

package queue;

import java.util.NoSuchElementException;

public interface InterfaceQueue<E> {

    int MAX_SIZE = 10;

    //入队(若失败则抛出IllegalStateException异常)
    E add(E element) throws IllegalStateException;

    //将指定元素插入队列,成功返回true,否则返回false
    boolean offer(E element);

    //获取队头的值,但不出队(若队列为空则抛出异常NoSuchElementException)
    E element() throws NoSuchElementException;

    //获取队头的值,但不出队(若队列为空则返回null
    E peek();

    //获取并移除队头(若队列空则返回null)
    E poll();

    //获取并移除队头(若队列空则抛出NoSuchElementException异常)
    E remove() throws NoSuchElementException;

    //获取当前队列中元素个数
    int size();

    //是否为空
    boolean isEmpty();

    //检查当前队列大小是否符合要求
    boolean checkSize();

}

数组实现队列ArrayQueue.java

底层以Object数组来存储队列中的元素,声明cursor作为游标,cursor总是指向数组中的下一个空位置下标,操作数组队列时总是删除数组第一个元素,在数组尾部新增元素,同时cursor也可以表示为当前队列中元素的个数。

package queue;

import java.util.Arrays;
import java.util.NoSuchElementException;

/**
 * @Author cuizx
 * @Description 基于数组实现队列,该数组队列是固定长度的,如果超过了最大值则拒绝进入队列
 * @Date 2019/10/2 11:15
 * @Param
 * @return
 **/
public class ArrayQueue<E> implements InterfaceQueue<E>{

    //记录数组队列中可以插入元素的位置
    private int cursor;

    private Object[] elementData;

    public ArrayQueue(){
        elementData = new Object[MAX_SIZE];
        cursor = 0;
    }

    public E add(E element) throws IllegalStateException{
        if(checkSize()){
            elementData[cursor] = element;
            cursor++;
            return element;
        }
        throw new IllegalArgumentException();
    }

    public boolean offer(E element){
        if(checkSize()){
            elementData[cursor] = element;
            cursor++;
            return true;
        }
        return false;
    }

    public E element() throws NoSuchElementException{
        if(isEmpty()){
            throw new NoSuchElementException();
        }
        return (E)this.elementData[0];
    }

    public E peek(){
        if(isEmpty()){
            return null;
        }
        return (E)elementData[0];
    }

    public E poll(){
        if(isEmpty()){
            return null;
        }

        quickRemove();

        return (E)elementData[0];
    }


    public E remove() throws NoSuchElementException{
        if(isEmpty()){
            throw new NoSuchElementException();
        }

        quickRemove();

        return (E)elementData[0];
    }

    public int size(){
        return cursor;
    }

    //检查是否当前队列已满
    public boolean checkSize(){
        if(size() >= MAX_SIZE){
            return false;
        }
        return true;
    }

    public boolean isEmpty(){
        return size() == 0;
    }

    private void quickRemove(){
        E tempElement = (E)elementData[0];

        Object[] targetElementData = new Object[MAX_SIZE];

        System.arraycopy(elementData,1,targetElementData,0,MAX_SIZE-1);
        elementData = targetElementData;

        cursor--;

    }
    @Override
    public String toString() {
        return "ArrayQueue{" +
                "cursor=" + cursor +
                ", elementData=" + Arrays.toString(elementData) +
                ", MAX_SIZE=" + MAX_SIZE +
                '}';
    }
}

链表实现队列

声明头部节点和游标节点,头部节点总是最先入队的节点,游标节点总是指向队尾的节点,在操作时总是删除队头的节点,在队尾新增节点。声明私有静态类Node,Node中item存储元素,next存储下一个Node的内存地址。

package queue;

import java.util.NoSuchElementException;

public class LinkedQueue<E> implements InterfaceQueue<E>{

    //头部节点
    private LinkedQueue.Node headNode;

    //游标节点
    private LinkedQueue.Node cursorNode;

    //当前队列大小
    private int size;

    public LinkedQueue(){
        size = 0;
    }

    public E add(E element) throws IllegalStateException {
        if(checkSize()){
            if(isEmpty()){
                headNode = new LinkedQueue.Node<E>(element,null);
                cursorNode = headNode;
            }else{
                LinkedQueue.Node<E> tempNode = new LinkedQueue.Node<E>(element,null);
                cursorNode.next = tempNode;
                cursorNode = cursorNode.next;
            }
            size++;
            return element;
        }
        throw new IllegalStateException();
    }

    public boolean offer(E element) {
        if(checkSize()){
            if(isEmpty()){
                headNode = new LinkedQueue.Node<E>(element,null);
                cursorNode = headNode;
            }else{
                LinkedQueue.Node<E> tempNode = new LinkedQueue.Node<E>(element,null);
                cursorNode.next = tempNode;
                cursorNode = cursorNode.next;
            }
            size++;
            return true;
        }
        return false;
    }

    public E element() throws NoSuchElementException {
        if(isEmpty()){
            throw new NoSuchElementException();
        }
        return (E)headNode.item;
    }

    public E peek() {
        if(isEmpty()){
            return null;
        }
        return (E)headNode.item;
    }

    public E poll() {
        if(isEmpty()){
            return null;
        }

        LinkedQueue.Node<E> tempNode = headNode;
        headNode = tempNode.next;
        size--;

        return (E)tempNode.item;
    }

    public E remove() throws NoSuchElementException {
        if(isEmpty()){
            throw new NoSuchElementException();
        }

        LinkedQueue.Node<E> tempNode = headNode;
        headNode = tempNode.next;
        size--;

        return (E)tempNode.item;
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        if(null == headNode){
            return true;
        }
        return false;
    }

    //检查是否当前队列已满
    public boolean checkSize(){
        if(size() >= MAX_SIZE){
            return false;
        }
        return true;
    }

    private static class Node<E> {
        E item;
        LinkedQueue.Node<E> next;

        Node(E item, LinkedQueue.Node<E> nextNode) {
            this.item = item;
            this.next = nextNode;
        }
    }

    @Override
    public String toString() {
        String headNodeStr = headNode ==null?"":headNode.item.toString();
        String cursorNodeStr = cursorNode ==null?"":cursorNode.item.toString();
        return "LinkedQueue{" +
                "headNode=" + headNodeStr +
                ", cursorNode=" + cursorNodeStr +
                ", size=" + size +
                '}';
    }
}

测试代码QueueTest.java 

package queue;

import java.util.Queue;

public class QueueTest {

    public static void main(String[] args) {
        testArrayQueue();
        System.out.println();
        testLinkedQueue();
    }

    private static void testArrayQueue(){
        System.out.println("数组实现的队列测试开始--------------------");
        InterfaceQueue<String> arrayQueue = new ArrayQueue();
        arrayQueue.add("1");
        arrayQueue.add("2");
        arrayQueue.add("3");
        System.out.println("插入元素123");
        System.out.println(arrayQueue.toString());

        System.out.println("插入元素4:"+arrayQueue.offer("4"));
        System.out.println(arrayQueue.toString());

        System.out.println("获取队列头的值:"+arrayQueue.element());
        System.out.println(arrayQueue.toString());

        System.out.println("获取队列头的值:"+arrayQueue.peek());
        System.out.println(arrayQueue.toString());

        System.out.println("获取并移除队头:"+arrayQueue.poll());
        System.out.println(arrayQueue.toString());

        System.out.println("移除队头:" + arrayQueue.remove());
        System.out.println(arrayQueue.toString());

        System.out.println("数组实现的列表测试结束--------------------");
    }

    private static void testLinkedQueue(){
        System.out.println("链表实现的队列测试开始--------------------");

        InterfaceQueue<String> linkedQueue = new LinkedQueue();

        linkedQueue.add("1");
        linkedQueue.add("2");
        linkedQueue.add("3");
        System.out.println("插入元素123");
        System.out.println(linkedQueue.toString());

        System.out.println("插入元素4:"+linkedQueue.offer("4"));
        System.out.println(linkedQueue.toString());

        System.out.println("获取队列头的值:"+linkedQueue.element());
        System.out.println(linkedQueue.toString());

        System.out.println("获取队列头的值:"+linkedQueue.peek());
        System.out.println(linkedQueue.toString());

        System.out.println("获取并移除队头:"+linkedQueue.poll());
        System.out.println(linkedQueue.toString());

        System.out.println("移除队头:" + linkedQueue.remove());
        System.out.println(linkedQueue.toString());

        System.out.println("链表实现的队列测试结束--------------------");

    }
}

运行结果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值