java数组模拟队列和环形队列

java数组模拟队列和环形队列

要点

  1. 有序列表
  2. 先进先出

数组模拟队列

思路

  1. 需要maxSize(最大容量)
  2. 需要两个变量front和rear分别记录前后两端的下标
  3. front和rear都会根据数据输入输出而改变

添加数据的思路

  1. 当front == rear时(也就是空队列的时候)可以存入数据,将尾指针向后移一位:rear+1,
  2. 如果rear < maxSize-1时可以存入
  3. 如果rear == maxSize-1时,说明队列满了

代码实现

package com.algorithm.demo2;
/*
 * 数组模拟队列
 *
 * */

import java.util.Scanner;

public class ArrayQueueDemo {
    public static void main(String[] args) {
        // 实例化一个队列
        ArrayQueue arrayQueue = new ArrayQueue(3);
        // 接收用户输入
        char key = ' ';
        Scanner scanner = new Scanner(System.in);
        // 定义主菜单
        while (true) {
            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("==========================");

            // 接收一个字符
            key = scanner.nextLine().charAt(0);
            // switch判断
            switch (key) {
                case 's':
                    arrayQueue.showQueue();
                    break;
                case 'a':
                    System.out.println("请输入想添加的数字:");
                    int i = new Scanner(System.in).nextInt();
                    arrayQueue.addQueue(i);
                    break;
                case 'g':
                    int queue = arrayQueue.getQueue();
                    System.out.println("您拿到的数字为 => " + queue);
                    break;
                case 'h':
                    int head = arrayQueue.showHead();
                    System.out.println("队头元素为 => " + head);
                    break;
                case 'e':
                    System.exit(0);
            }
        }
    }
}

// 编写一个队列类
class ArrayQueue {
    private int maxSize;
    private int front;
    private int rear;
    private int[] arr;

    // 有参构造器,接收maxSize
    public ArrayQueue(int maxSize) {
        this.maxSize = maxSize;
        // 通过maxSize创建数组赋给arr
        this.arr = new int[maxSize];
        // 初始化front和rear
        this.front = -1; // 指向队列头的前一个位置
        this.rear = -1; // 指向队列尾
    }

    // 判断队列是否满
    public boolean isFull() {
        return (this.rear >= (this.maxSize - 1));
    }

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

    // 添加元素
    public void addQueue(int n) {
        // 判断队列是否满
        if (isFull()) {
            System.out.println("队列满了,不能加入");
            return;
        }
        // ++rear并赋值
        arr[++rear] = n;
    }

    // 获取数据
    public int getQueue() {
        // 判断队列是否空
        if (isEmpty()) {
            // 通过抛出异常来处理
            throw new RuntimeException("队列为空,无元素");
        }
        // ++front并取值
        return arr[++front];
    }

    // 显示队列的所有数据
    public void showQueue() {
        if (isEmpty()) {
            System.out.println("队列空的");
            return;
        }
        for (int i : this.arr) {
            System.out.print(i + "\t");
        }
        System.out.println();
    }

    // 显示队头数据
    public int showHead() {
        if (isEmpty()) {
            throw new RuntimeException("队列空的");
        }
        return (arr[front + 1]);
    }
}

数组模拟环形队列

思路

  1. 改变front变量的含义:现在 front指向队列的第一个元素,初始值为0
  2. 改变rear变量的含有:现在 rear指向队列最后一个元素的后一个元素,初始值为0
  3. 此时队列满时为:(rear + 1) % maxSize == front
  4. 此时队列为空时为:rear == front
  5. 此时队列中有效个数为:(rear - front + maxSize) % maxSize

代码实现

package com.algorithm.demo3;
/*
 * 数组实现环形队列
 *
 *
 * */

import java.util.Scanner;

public class CircleArrayDemo {
    public static void main(String[] args) {
        // 实例化队列
        CircleArray circleArray = new CircleArray(3);

        // 接收用户输入
        char key = ' ';
        Scanner scanner = new Scanner(System.in);
        // 定义主菜单
        while (true) {
            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("==========================");

            // 接收一个字符
            key = scanner.nextLine().charAt(0);
            // switch判断
            switch (key) {
                case 's':
                    circleArray.show();
                    break;
                case 'a':
                    System.out.println("请输入想添加的数字:");
                    int i = new Scanner(System.in).nextInt();
                    circleArray.add(i);
                    break;
                case 'g':
                    int queue = circleArray.get();
                    System.out.println("您拿到的数字为 => " + queue);
                    break;
                case 'h':
                    int head = circleArray.showHead();
                    System.out.println("队头元素为 => " + head);
                    break;
                case 'e':
                    System.exit(0);
            }
        }
    }
}

// 环形队列类
class CircleArray {
    private int maxSize;
    private int front;
    private int rear;
    private int[] arr;

    // 构造器
    public CircleArray(int maxSize) {
        this.maxSize = maxSize;
        this.arr = new int[maxSize];
    }

    // 判断是否为满
    private boolean isFull() {
        return ((this.rear + 1) % this.maxSize == this.front);
    }

    // 判断是否为空
    private boolean isEmpty() {
        return (this.rear == this.front);
    }

    // 添加
    public void add(int n) {
        if (isFull()) {
            System.out.println("满了,添加不了");
            return;
        }
        // 赋值
        this.arr[this.rear] = n;
        // 改变rear指向
        this.rear = (this.rear + 1) % this.maxSize;
    }

    // 拿出
    public int get() {
        if (isEmpty()) {
            throw new RuntimeException("空的,没数据");
        }
        // 保存临时值用于返回,返回前需要改变front的指向
        int tem = this.arr[this.front];
        // 改变front指向
        this.front = (this.front + 1) % this.maxSize;
        return tem;
    }

    // 查看队列
    public void show() {
        if (isEmpty()) {
            System.out.println("空的,没东西");
            return;
        }

        /*
         * 遍历思路:
         *   从front开始,到有效个数长度
         * */

        // 拿到有效长度
        int length = ((this.rear + this.maxSize - this.front) % this.maxSize);
        System.out.println("一共有" + length + "个数据");
        // 遍历
        for (int i = this.front; i < (this.front + length); ++i) {
            System.out.println("第" + (i % this.maxSize) + "个数据是  =>  " + this.arr[(i % maxSize)]);
        }
    }

    // 显示队头数据
    public int showHead() {
        if (isEmpty()) {
            throw new RuntimeException("队列空的");
        }
        return (this.arr[this.front]);
    }
}

posted @ 2022-02-28 21:16  CoderCatIce  阅读(29)  评论(0编辑  收藏  举报