分析:

➢对数组模拟队列问题分析并优化:

1)目前数组使用一次就不能用, 没有达到复用的效果

2)将这个数组使用算法,改进成一个环形的数组取模:%

 数组模拟环形队列_队列

 

 

实现:

定义队列类

private int maxSize;//数组的最大容量
private int front;//头结点,初始值为0,指向队列的第一个元素
private int read;//尾结点,初始值为0,指向元素的最后一个元素的后一个位置
private int[] arr;//创建数组用于存放数据,模拟队列

 

初始化队列

     /**
         * 构造方法
         * @param arrMaxSize 队列能够拥有的最大容量
         */
        public CircularQueue(int arrMaxSize){
            maxSize = arrMaxSize;//传入数据表示队列能够拥有的最大容量
            arr = new int[maxSize];//初始化数组
            front = 0;//指向队列头结点
            read = 0;//指向的是队列的尾结点
        }

队满

        /**
         * 判断队列是否满了,判断队列是否满的条件是:(read+1)%maxSize == front
         * @return
         */
        public boolean isFull(){
            return (read+1)%maxSize == front;
        }

队空

     /**
         * 判断队列是否为空
         * @return
         */
        public boolean isAir(){
            return front == read;
        }

 

添加数据

        /**
         * 添加数据到队列
         * @param data:添加的数据
         */
        public void add(int data){
            //先判断队列是否满
            if (isFull()){
                System.out.println("队列已满,不能加入数据!");
                return;
            }
            //直接将数据加入
            arr[read] = data;
            read = (read+1) % maxSize;
        }    

 

出队列

         /**
         * 获取队列的数据,出队列
         * @return
         */
        public int get(){
            //先判断队列是否为空
            if (isAir()){
                //通过抛出异常来解决
                throw new RuntimeException("队列空,不能取数据!");
            }
            /**
             * //这里需要分析出front是指向队列的第一个元素
             * // 1.先把front对应的值保留到一个临时变量
             * // 2.将front后移,考虑取模,如果直接++回报下标越界异常
             * // 3.将临时保存的变量返回
             */
            int value = arr[front];
            front = (front + 1)%maxSize;
            return value;
        }    

 

获取当前队列有效个数

        /**
         * 求出当前队列有效数据的个数
         */
        public int size(){
            return (read+maxSize-front)%maxSize;
        }    

 

打印队列

    /**
         * 打印数据,就是遍历arr数组
         */
        public void listQueue(){
            //判断队列是否为空
            if (isAir()){
                System.out.println("队列为空,没有数据!");
            }
            //从front开始遍历,遍历多少个元素
            for (int i=front;i<front+size();i++){
                System.out.println("arr["+i%maxSize+"]="+arr[i%maxSize]);
            }
        }

 

显示队头

 

     /**
         * 显示队列的头数据
         */
        public int headQueue(){
            if (isAir()){
                throw new RuntimeException("队列是空的没有数据");
            }
            return arr[front];
        }

完整代码:

数组模拟环形队列_队列_02数组模拟环形队列_队列_03
import java.util.Scanner;

//Circular queue
public class Test03_数组模拟环形队列 {
    public static void main(String[] args) {
        CircularQueue queue = new CircularQueue(4);//最多只能存储三个有效数据,因为设置的是有一个预留的空间
        char value = ' ';
        Scanner s = new Scanner(System.in);
        boolean loop = true;
        while (loop){
            System.out.println("==================================");
            System.out.println("s(show):显示队列");
            System.out.println("e(exit):退出程序" );
            System.out.println("a(add):添加数据到队列");
            System.out.println("g(get):从队列取出数据");
            System.out.println("h(head):查看队列头的数据");
            System.out.println("==================================");
            //接受用户输入的一个字符
            System.out.print("请输入指令:");
            value = s.next().charAt(0);
            switch (value){
                case 's'://显示队列
                    queue.listQueue();
                    break;
                case  'g'://取数据
                    System.out.println("取出的数据是:"+queue.get());
                    break;
                case 'a'://添加数据
                    System.out.print("请输入一个数:");
                    int index = s.nextInt();
                    queue.add(index);
                    break;
                case 'h'://查看队列头
                    System.out.println("队列的头是:"+queue.headQueue());
                    break;
                case 'e'://退出程序
                    loop = false;
                    break;
                default:
                    System.out.println("您好,您输入的字符不合法,请重新输入!");
                    break;
            }
        }
        System.out.println("您已经成功退出!");
    }
}

class CircularQueue{
        private int maxSize;//数组的最大容量
        private int front;//头结点,初始值为0,指向队列的第一个元素
        private int read;//尾结点,初始值为0,指向元素的最后一个元素的后一个位置
        private int[] arr;//创建数组用于存放数据,模拟队列

        /**
         * 构造方法
         * @param arrMaxSize 队列能够拥有的最大容量
         */
        public CircularQueue(int arrMaxSize){
            maxSize = arrMaxSize;//传入数据表示队列能够拥有的最大容量
            arr = new int[maxSize];//初始化数组
            front = 0;//指向队列头结点
            read = 0;//指向的是队列的尾结点
        }

        /**
         * 判断队列是否满了,判断队列是否满的条件是:(read+1)%maxSize == front
         * @return
         */
        public boolean isFull(){
            return (read+1)%maxSize == front;
        }

        /**
         * 判断队列是否为空
         * @return
         */
        public boolean isAir(){
            return front == read;
        }

        /**
         * 添加数据到队列
         * @param data:添加的数据
         */
        public void add(int data){
            //先判断队列是否满
            if (isFull()){
                System.out.println("队列已满,不能加入数据!");
                return;
            }
            //直接将数据加入
            arr[read] = data;
            read = (read+1) % maxSize;
        }

        /**
         * 获取队列的数据,出队列
         * @return
         */
        public int get(){
            //先判断队列是否为空
            if (isAir()){
                //通过抛出异常来解决
                throw new RuntimeException("队列空,不能取数据!");
            }
            /**
             * //这里需要分析出front是指向队列的第一个元素
             * // 1.先把front对应的值保留到一个临时变量
             * // 2.将front后移,考虑取模,如果直接++回报下标越界异常
             * // 3.将临时保存的变量返回
             */
            int value = arr[front];
            front = (front + 1)%maxSize;
            return value;
        }
        /**
         * 求出当前队列有效数据的个数
         */
        public int size(){
            return (read+maxSize-front)%maxSize;
        }
        /**
         * 打印数据,就是遍历arr数组
         */
        public void listQueue(){
            //判断队列是否为空
            if (isAir()){
                System.out.println("队列为空,没有数据!");
            }
            //从front开始遍历,遍历多少个元素
            for (int i=front;i<front+size();i++){
                System.out.println("arr["+i%maxSize+"]="+arr[i%maxSize]);
            }
        }
        /**
         * 显示队列的头数据
         */
        public int headQueue(){
            if (isAir()){
                throw new RuntimeException("队列是空的没有数据");
            }
            return arr[front];
        }
    }
View Code