JAVA-循环队列

前言

队列作为一种特殊的线性表,存在顺序储存和链式储存。今天先记录下顺序储存。

首先,先来理一下思路


所谓的顺序储存就是用数组来储存数据

  JAVA和C语言不同,他没有指针,所以我们需要创建两个类似于指针的索引,用他们对数组进行操作:

  1. 定义一个front变量,让它一直指向队列中有效数据的第一个元素设它的初始值为0

  2. 定义一个rear变量,让它一直指向队列中有效数据中最后一个元素的后一个位置,所以创建数组的时候,数组的大小应该是你想存的储数据个数 + 1,这种方式要牺牲一个空间,rear的初始值也为0
    (maxSize是数组的长度)

  3. 当队列满的时候,他的条件应该是:

(rear + 1) % maxSize = frong
  1. 当队列为空的时候:
rear == front
  1. 当我们分析,队列有效数据的个数时:
(rear - front + maxSize) % maxSize

这几个主要用到的都是取模的思想
JAVA-循环队列_第1张图片


下面实现具体功能

  1. 创建一个类用来建立队列和实现他的一些功能

    class circleArray {
        private int maxSize;
        private int front;
        private int rear;
        private int[] arr;
    
        public circleArray(int maxSize) {
            this.maxSize = maxSize;
            front = 0; // 指向对猎头部
            rear = 0; // 指向队列尾部
            arr = new int[maxSize];
        }
    ................
    }
    
    
    

    下面为该类的具体方法

  2. 检查队列元素是否已满

    // 检查元素是否已满
    public boolean isFull() {
        return (rear + 1) % maxSize == front;
    }
    
  3. 检查队列是否为空

    // 检查列表是否为空
    public boolean isEmpty() {
        return rear == front;
    }
    
  4. 向列表中添加元素

     public void enQueue(int n) {
        if(isFull()){
            System.out.println("队列已满,不能添加元素~~~~");
            return;
        }
        arr[rear] = n;
        rear = (rear + 1) % maxSize;
    }   
    
  5. 取出队列中的元素

     public int getQueue() {
        if(isEmpty()) {
            throw new RuntimeException("队列为空,取不出数据~~~~");
        }
        int value = arr[front];
        front = (front + 1) % maxSize;
        return value;
    }
    
  6. 求队列的有效长度

    public int queueLength() {
        return (rear - front + maxSize) % maxSize;
    }
    
  7. 清空队列,重置

    public void clearQueue() {
        front = 0;
        rear = 0;
        System.out.println("列表已经清空~~~~~~");
    }
    
  8. 展示队列

    public void showQueue() {
        if(isEmpty()) {
            System.out.println("队列为空,没有数据~~~~~~~~~~");
            return;
        }
        for(int i = front; i < front +queueLength(); i++) {
            System.out.printf("arr[%d]=%d\n",i % maxSize,arr[i % maxSize]);
        }
    }
    
  9. 显示队列的头部数据

    public int headQueue() {
        if(isEmpty()) {
            throw new RuntimeException("队列为空,没有数据");
        }
        return arr[front];
    }
    

下面为具体的主函数

public static void main(String[] args) {
        // 最大存储数据为 5-1 = 4
        circleArray circlearray = new circleArray(5);
        int num;
        Scanner scanner = new Scanner(System.in);
        boolean loop = true;

        while(loop) {
            System.out.println("==========================");
            System.out.println("1(enQueue):向队列中添加元素");
            System.out.println("2(getQueue):取出队列的元素");
            System.out.println("3(showQueue):展示队列");
            System.out.println("4(headQueue):展示队列的头数据");
            System.out.println("5(clearQueue):清空列表");
            System.out.println("6(exit):退出队列");
            System.out.println("==========================");
            System.out.print("请选择你想要进行的操作:");
            num = scanner.nextInt();
            switch (num) {
                case 1 :
                    System.out.print("请输入你要添加的元素:");
                    int value_1 = scanner.nextInt();
                    circlearray.enQueue(value_1);
                    break;
                case 2 :
                    try {
                        int value_2 = circlearray.getQueue();
                        System.out.printf("取出的数据是:%d",value_2);
                        System.out.println("==========================");
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 3 :
                    circlearray.showQueue();
                    break;
                case 4 :
                    try {
                        int value_2 = circlearray.headQueue();
                        System.out.println("==========================");
                        System.out.printf("头部的数据是:%d",value_2);
                        System.out.println("==========================");
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 5 :
                    circlearray.clearQueue();
                    break;
                case 6 :
                    scanner.close();
                    loop = false;
                    break;
                default:
                    break;

            }
        }
        System.out.println("程序退出.............");
    }
  • 总结


    总体来说比较简单,重点讲一下这里的取模,首先

    front = (front + 1) % maxSize;
    (rear + 1) % maxSize == front;
    

    这两个取模运算是为了,当他们两个都位于队列尾部时,如果还要添加元素,或者删除元素的时候,那么他们只要一进行+1操作的话肯定就会跑到队列外面去,那么循环队列就不成立了,这里的取模就是防止他们越界


    计算队列有效个数时用到的:

    (rear - front + maxSize) % maxSize;
    

    这里跟上面意思差不多

队空:front==rear
队满: (rear+1) mod maxsize ==front
队中元素个数n=(rear-front+maxsize )mod maxsize
入队:rear=(rear+1) % maxsize ;
出队:front=(front+1) % maxsize ;

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