欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【数据结构+算法】队列——用数组实现环形队列(JAVA)

程序员文章站 2022-03-12 23:04:43
...

在我上一个博客中,我们提到数组实现队列时,不能实现代码的复用,优化方法是可以改成一个环形的数组(进行取余)。所以本次我将总结如何用数组实现环形队列。

思路:

1、对front变量进行一个调整:front指向队列的第一个元素,即arr[front]为队列的第一个元素;front=0

2、对rear变量也进行相应的调整:reart指向队列最后一个元素的后一个位置,预留一个空间;rear=0

3、队满:(rear+1) % maxSize = front

4、对空:rear == front

5、队列中的有效数据:(rear + maxSize - front) % maxSize
(rear可能小于maxSize,取余是为了获取在环形队列上真实位置)

具体实现代码如下:
(1)、判断队列是否满
(2)、判断队列是否为空
(3)、添加数据到队列中
(4)、获取队列的数据,出队列;
(5)、显示当前队列数据;
(6)、显示队列的头数据,注意不是取出数据;

package com.ycx.queue;

import java.util.Scanner;

public class CircleArrayQueueDemo {
    public static void main(String[] args) {

        //测试
        System.out.println("测试数组模拟环形队列");

        //创建一个环形队列
        CircleArray queue = new CircleArray(4);//有一个空位置 有效数据最大是3
        char key = ' ';//接受用户输入
        Scanner input = new Scanner(System.in);
        boolean flag = true; //控制循环 默认死循环

        //输出菜单
        while (flag){
            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),查看队列头的数据");

            key=input.next().charAt(0);//接受收一个字符
            switch (key){
                case 's':
                    queue.showQueue();
                    break;
                case 'a':
                    System.out.println("输一个数");
                    int val=input.nextInt();
                    queue.addQueue(val);
                    break;
                case 'g':   //取出数据  因为方法里面抛出了异常 所以这里需要捕获
                    try{
                        int res=queue.getQueue();
                        System.out.printf("取出的数据为%d\n",res);
                    }catch (Exception e){
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'h':
                    try{
                        int res=queue.headQueue();
                        System.out.printf("队列头的数据为%d\n",res);
                    }catch (Exception e){
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'e':    //退出程序
                    input.close();//关闭
                    flag=false;
                    break;

                default:
                    break;
            }
        }
        System.out.println("程序退出");
    }
}


class CircleArray{
    private  int maxSize;
    //表示数组的最大容量
    private  int front;
    //front变量含义做一个调整:指向队列的第一个元素,arr[front]即为队列的第一个元素
    //front=0
    private  int rear;
    //rear变量含义做一个调整:rear指向队列的最后一个元素的后一个位置,预留一个位置
    //rear=0
    private  int[] arr;
    // 该数组用于存放数据,模拟队列


    public CircleArray(int arrMaxSize){
        maxSize = arrMaxSize;
        arr = new int[maxSize];
        front=0;
        rear=0;
    }


    //1.判断队列是否满
    public boolean isFull(){
        return (rear+1)%maxSize==front;
    }

    //2.判断队列是否为空
    public boolean isEmpty(){
        return rear==front;
    }


    //3.添加数据到队列中
    public void addQueue(int n) {
        //判断队列是否为满
        if (isFull()) {
            System.out.println("队列已满,不能加入数据");
        }
        arr[rear] = n;
        //直接将数据加入 因为rear本身指的就是 后一个元素
        rear = (rear + 1) % n;
        //将rear 后移 并取模 (环形 当rear走到最后一个位置时,取模就可以到前面的位置)
    }

        //4.获取队列的数据,出队列
        public  int getQueue(){
            if(isEmpty()){
                throw new RuntimeException("队列空,不能取数据");
            }

            //这里需要分析出front是指向队列的第一个元素
            //①. 先把front对应的值保留到一个临时变量;
            //②. 将front后移,考取取模(因为front也可能走到最后一个元素,就会越界)
            //③. 将临时保存的变量返回
            int value = arr[front];
            front = (front+1) % maxSize;
            return value;
        }


        //5.显示当前队列数据
    public void showQueue() {
        //遍历
        if(isEmpty()){
            System.out.println("当前队列为空");
            return;
        }

        //思路: 从front开始遍历 一共有front+有效数据个数
        for (int i = front ;i <front+size(); i++) {
            System.out.printf("arr[%d]=%d\n",i%maxSize,arr[i%maxSize]); //格式化输出
                                             // i可能也会超出下标(环形)
        }
    }

    //求出当前有效数据个数
    public int size(){
        return (rear+maxSize-front)%maxSize;
        // rear=1 front=0 maxSize=3
    }


    //6.显示队列的头数据,注意不是取出数据
    public int headQueue(){
        if(isEmpty()){
            throw new RuntimeException("队列为空");
        }
        return arr[front]; //注意:front本身就指向第一个元素
    }



}

运行结果如下:
【数据结构+算法】队列——用数组实现环形队列(JAVA)