队列

前言

本博客是学习韩顺平老师的数据结构与算法教程后记录的

队列介绍

  • 队列是一个有序列表,可以用数组或是链表来实现
  • 遵循先入先出的原则,即:先存入队列的数据要先取出,后存入的要后取出

使用数组实现队列

队列_第1张图片

class ArrayQueue {
    /**
     * 队列头
     */
    private int front;
    /**
     * 队列尾
     */
    private int rear;
    /**
     * 数组总长度
     */
    private int maxSize;
    /**
     * 数组
     */
    private int[] array;

    /**
     * desc : 初始化队列
     * create_user : cheng
     * create_date : 2020/6/30 13:57
     */
    public ArrayQueue(int maxSize) {
        this.maxSize = maxSize;
        this.array = new int[maxSize];
        this.front = -1;
        this.rear = -1;
    }

    /**
     * desc : 判断队列是否已满
     * create_user : cheng
     * create_date : 2020/6/30 14:19
     */
    public boolean isFull() {
        return rear == maxSize - 1;
    }

    /**
     * desc : 判断队列是否为空
     * create_user : cheng
     * create_date : 2020/6/30 14:20
     */
    public boolean isEmpty() {
        return front == rear;
    }

    /**
     * desc : 添加一个元素
     * create_user : cheng
     * create_date : 2020/6/30 14:20
     */
    public void addQueue(int item) {
    	// 判断队列是有已满
        if (isFull()) {
            System.out.println("队列已满,添加失败");
            return;
        }
		
		// 尾指针后移,添加数据
        array[++rear] = item;
    }

    /**
     * desc : 获取一个元素
     * create_user : cheng
     * create_date : 2020/6/30 14:22
     */
    public int getQueue() {
    	// 判断队列是否为空
        if (isEmpty()) {
            throw new RuntimeException("队列为空");
        }

		// 头指针后移,获取数据
        return array[++front];
    }

}

优化

上述队列存在的明显问题就是数组只能使用一次,使用算法,将数组优化成环形队列(采用取模%的方式)
可以简单类比成钟表,方便理解
队列_第2张图片

class ArrayQueue2 {
    /**
     * 队列头,指向队列的第一个元素,array[front]就是队列的第一个元素
     */
    private int front;
    /**
     * 队列尾,指向队列的最后一个元素的后一个位置
     */
    private int rear;
    /**
     * 数组总长度
     */
    private int maxSize;
    /**
     * 数组
     */
    private int[] array;

    /**
     * desc : 初始化队列
     * create_user : cheng
     * create_date : 2020/6/30 14:49
     */
    public ArrayQueue2(int maxSize) {
    	// 数组的总长度要比实际传入的队列大小+1,因为采用这种方式时,rear尾指针所指向的位置总是空的
        maxSize++;
        this.maxSize = maxSize;
        array = new int[maxSize];
    }

    /**
     * desc : 判断队列是否已满
     * create_user : cheng
     * create_date : 2020/6/30 14:19
     */
    public boolean isFull() {
        // 如果尾指针下一个元素就是front,那么说明队列已满,实际上这个时候队列还是有一个空的位置
        return (rear + 1) % maxSize == front;
    }

    /**
     * desc : 判断队列是否为空
     * create_user : cheng
     * create_date : 2020/6/30 14:20
     */
    public boolean isEmpty() {
        return front == rear;
    }

    /**
     * desc : 添加一个元素
     * create_user : cheng
     * create_date : 2020/6/30 14:20
     */
    public void addQueue(int item) {
        // 判断队列是否已满
        if (isFull()) {
            System.out.println("队列已满,添加失败");
            return;
        }

        // 没满就添加数据
        array[rear] = item;
        // 后移尾指针
        rear = (rear + 1) % maxSize;
    }

    /**
     * desc : 获取一个元素
     * create_user : cheng
     * create_date : 2020/6/30 14:22
     */
    public int getQueue() {
        // 判断队列是不是空的
        if (isEmpty()) {
            throw new RuntimeException("队列为空");
        }

        // 获取队列的第一个元素
        int value = array[front];
        // 后移头指针
        front = (front + 1) % maxSize;
        // 返回元素
        return value;
    }

    public int size() {
        // 尾指针位置 - 头指针位置
        // 加上maxSize 防止模出负数 因为这是一个环形队列, 尾指针的值可能小于头指针的值
        return (rear - front + maxSize) % maxSize;
    }

}

你可能感兴趣的:(数据结构与算法)