手写一个队列数据结构

实现队列的思路

队列数据结构是动态集合的一种,它实现的是一种先进先出(first-in, first-out)FIFO策略。队列一般支持入队(enqueue),出队(dequeue)操作。实现上可以用数组A(实际上使用链表来实现队列比使用数组更优)作为栈底层数据存储,通过属性headerIndex来记录队列头(最先入队的元素)下标位置,footerIndex来记录队列尾巴(最后入队的元素)下标位置,(footerIndex - headerIndex)作为队列总元素数量(length)。

  每次调用入队(enqueue)函数时,需要先判断底层数组长度是否足够容纳新的元素(A.length < footerIndex + 1),如果不够需要继续判断是否有出队,如果有出队(headerIndex > 0)可以将数组所有元素往前面(0)下标移动,如果没有出队(headerIndex = 0),可以按照给定的算法进行数组扩容。最后将元素保存到数组(footerIndex + 1)下标,然后将(footerIndex = footerIndex -1)作为队列最后入队(队列尾)下标。

  每次调用出队函数时,需要先判断底层数组是否为空,如果为空则数组越界异常,否则返回headerIndex元素(FIFO),将headerIndex下标置为null,最后将(headerIndex = headerIndex + 1)作为队列最开始入队(队列头)下标。                

              

实现队列的代码

/**
 * <p>
 * 数据结构 - 队列 - 先进先出(FIFO first-in first-out)
 * </p>
 *
 * @author laizhiyuan
 * @since 2019/9/25.
 */
public class Queue<T> {




    private Object[] dataElement;
    private int headerIndex = 0;
    private int footerIndex = 0;
    private static final int DEFAULT_INIT_CAPACITY = 10;


    public Queue() {


        this.dataElement = new Object[DEFAULT_INIT_CAPACITY];
    }


    public Queue(int capacity) {


        if (capacity < 0) {
            throw new IllegalArgumentException("capacity can not than less 0");
        }
        this.dataElement = new Object[capacity];
    }




    /**
     * 入队
     *
     * @param ele 新元素
     */
    public void enqueue(T ele) {


        //判断数组长度是否足够容纳新的元素
        if (this.dataElement.length < (this.footerIndex + 1)) {
            if (this.headerIndex > 0) {


                //记录出队数量
                int enqueueNum = this.headerIndex;
                //如果已经出队一部分, 则把全部元素往前移动一下
                System.arraycopy(this.dataElement, this.headerIndex, this.dataElement, 0, this.length());


                //重新计算队列头尾下标
                this.headerIndex = 0;
                this.footerIndex = this.footerIndex - enqueueNum;
            } else {


                //如果没有任何出队,则要扩容数组长度为原来的长度+原来长度 / 2
                int newLength = this.dataElement.length + (this.dataElement.length >> 1);
                this.dataElement = Arrays.copyOf(this.dataElement, newLength);
            }
        }


        //将新元素保存到(footerIndex)位置
        this.dataElement[this.footerIndex++] = ele;
    }


    /**
     * 出队
     *
     * @return 返回出队元素
     */
    @SuppressWarnings("unchecked")
    public T dequeue() {
        if (this.isEmpty()){
            throw new ArrayIndexOutOfBoundsException(this.length() - 1);
        }
        Object o = this.dataElement[this.headerIndex];
        this.dataElement[this.headerIndex] = null;
        this.headerIndex = this.headerIndex + 1;


        return (T) o;
    }




    public int length() {
        return this.footerIndex - this.headerIndex;
    }


    public boolean isEmpty() {
        return this.length() <= 0;
    }

测试队列代码

public static void main(String[] args) {


        Queue<String> queue = new Queue<>();


        System.out.println(queue.length());
        System.out.println(queue.isEmpty());




        //footer = 0 + 1, header=0
        queue.enqueue("Q1");
        //footer = 1 + 1, header=0
        queue.enqueue("Q2");
        queue.enqueue("Q3");
        queue.enqueue("Q4");
        queue.enqueue("Q5");
        queue.enqueue("Q6");
        queue.enqueue("Q7");
        queue.enqueue("Q8");
        queue.enqueue("Q9");
        //footer = 9 + 1, header=0
        queue.enqueue("Q10");


        System.out.println(queue.length());
        //value=Q1, footer = 9 + 1, header=0 + 1
        System.out.println(queue.dequeue());
        System.out.println(queue.length());


        //注意这一步会发生移动数组元素
        //因为出队一次(header > 0),且(this.dataElement.length < (this.footerIndex + 1)
        queue.enqueue("Q11");
        System.out.println(queue.length());


        //注意这里会发生扩容
        //因为footer + 1大于数组长度且header等于0
        queue.enqueue("Q12");
        queue.enqueue("Q13");
        queue.enqueue("Q14");
        queue.enqueue("Q15");
        queue.enqueue("Q16");
        queue.enqueue("Q17");
        System.out.println(queue.length());
        System.out.println(queue.isEmpty());




        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
        System.out.println(queue.dequeue());
    }

验证队列输出

0
true
10
Q1
9
10
16
false
Q2
Q3
Q4
Q5
Q6
Q7

虽然实现队列代码不多,但是理解队列原理和实现的思路很重要。

-END-

    长按扫码关注【Java软件编程之家】公众号,一起学习,一起成长!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值