尚硅谷数据结构循环数组队列(问题的看法)

前言

提示:看了老师视频有些疑惑:这里我自己看法

主要参考了尚硅谷韩老师视频和大话数据结构p115


一、直接上代码

package com.QueueStudy;

/**
 * 解决arrayQueue的问题
 *
 * 1)目前数组使用一次就不能用,没有达到复用的效果
 * 2)将这个数组使用算法,改进成一个环形的队列取模:%
 */
public class CircleArrayQueue {
    
    
    private int maxSize;//表示数组的最大容量
    private int front;//指向队列头
    /**
     * 为啥队尾这样设计呢?
     * 如果指向队尾元素那么判断队列为空和当队列为1个元素
     * 条件都为front == rear 不好处理了
     *
     * 所以我们约定rear指向队尾的下一个元素
     */
    private int rear;//队列尾的下一个元素

    private int[] arr;//该数据用于存放数据,模拟队列




    public CircleArrayQueue(int maxSize) {
    
    
        this.maxSize = maxSize;
        this.arr = new int[maxSize];
        front = 0;//指向队列头部,分析出front是指向队列头的前一个位置。
        rear = 0;//指向队列尾,指向队列尾的数据(即就是队列最后一个数据)

    }

    //判断队列是否满

    /**
     * 方法一:front == rear % maxSize
     * 这个和判断队列为空一样了(front == rear 等价于front == rear % maxSize)
     * 你还得另外这是flag进行区分(具体查看大话数据结构p115)
     *
     * 方法二:我么约定队列满了情况下其实还有1个空位
     * 这样判断队列满 (rear + 1)%maxSize == front
     * 和队列为空区分
     * @return
     */
    public boolean ifFull(){
    
    
        return (rear + 1)%maxSize == front;
    }
    //判断队列是否为空
    public boolean isEmpty(){
    
    
        return rear == front;
    }

    //添加数据到队列

    /**
     * (rear + 1) % maxSize 中取模 maxSize目的走到队列尾部能够返回0位置
     * rear + 1 为了rear指向队尾下一个元素(这是我们之前约定)
     * @param n
     */
    public void addQueue(int n){
    
    
        if (ifFull()){
    
    
            System.out.println("队列满,不能加入数据");
            return;
        }
        arr[rear] = n;
        rear = (rear + 1) % maxSize;
    }

    //获取队列的数据,出队列
    public int getQueue(){
    
    
        if (isEmpty()){
    
    
            throw new RuntimeException("队列空,不能取出数据");
        }
        int temp = arr[front];
        front = (front + 1) % maxSize;
        return temp;
    }


    //显示队列的所有数据

    /**
     * i % maxSize 取数据能够返回0位置
     */
    public void show(){
    
    
        if (isEmpty()){
    
    
            System.out.println("队列空的,没有数据");
        }
        for (int i = front;i < front + getSize();i++){
    
    
            System.out.print(arr[i % maxSize] + " ");

        }

    }

    //显示队列的头数据,注意不是取出数据
    public int headQueue(){
    
    
        if (isEmpty()){
    
    
            throw new RuntimeException("队列空的,没有数据");
        }
        return arr[front];
    }

    /**
     * 获取队列个数
     * front 在 rear的左边(rear > front)
     * 1.队列个数 = rear  - front
     *
     * front 在 rear的右边(rear < front)
     * 2.队列个数 = maxSize - front + 0 + rear = rear - front + maxSize
     *
     * 至于为啥取模?
     * 你可以想 咋才能用一个公式表示上述两个公式
     * 公式1 算出来差值 大于0的 那么 你+一个数再取这个数的模等于个数组
     * 比如 (2 + 3) % 3 = 3
     *
     *公式二
     * 由于rear - front 他是小于0 并且 + 一个数 那么你直接取模 还是这个数字
     *
     *
     * 比如 (-2 + 3)% 3 = 1
     *      而 原来 -2 + 3 等于1
     *  这个成立条件 前边小于0的这个数 绝对值 小于 后边那个正数的
     *  当前问题 前边数字负数的绝对值一定小于数组容量
     *
     * 所以 用一个公式包含1和2 就是 (rear - front + maxSize)%maxSize
     * @return
     */
    public int getSize(){
    
    
        return (rear - front + maxSize)%maxSize;
    }



}
class QueueTest(){
    
    

	@Test
    public void testCircleArrayQueue(){
    
    

        CircleArrayQueue queue = new CircleArrayQueue(3);
        queue.addQueue(1);
        queue.addQueue(2);
        //注意这时候数组还有1个空位置,但是这时候我们约定数组已经满了
        int queueQueue = queue.getQueue();
        System.out.println("获取1个元素 " + queueQueue);
        //把3插入下表2数组中 数组0空
        queue.addQueue(3);

        queue.show();
    }
}

总结

这是我自己一些看法
内容参考尚硅谷韩老师数据结构与算法
代码注释中参考大话数据结构p115

猜你喜欢

转载自blog.csdn.net/prjh_/article/details/125402660
今日推荐