Java 队列

基本介绍

 数组模拟队列

思路分析

Java 队列_第1张图片

Java 队列_第2张图片 代码实现

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        // 创建一个队列
        ArrayQueue queue = new ArrayQueue(3);
        int select;
        Scanner scanner = new Scanner(System.in);
        boolean loop = true;

        while (loop) {
            System.out.println("\n----------队列操作菜单-----------");
            System.out.println("1、查看队列");
            System.out.println("2、添加数据到队列");
            System.out.println("3、取出队列元素");
            System.out.println("4、退出菜单");
            System.out.println("请选择:");

            select = scanner.nextInt();
            switch (select) {
                case 1: {
                    queue.showQueue();
                    break;
                }
                case 2: {
                    System.out.println("请输入要添加的数据(数字类型):");
                    int data = scanner.nextInt();
                    queue.pushQueue(data);
                    break;
                }
                case 3: {
                    try {
                        int data = queue.popQueue();
                        System.out.println("队头元素为:" + data);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                }
                case 4: {
                    loop = false;
                    break;
                }
            }
        }
        scanner.close();
    }
}

// 用数组模拟队列
class ArrayQueue {
    private int maxSize; // 队列的最大容量
    private int front; // 队头指针
    private int rear; // 队尾指针
    private int[] queue; // 队列,用于存储数据,此处用数组模拟

    ArrayQueue(int maxSize) {
        // 初始化数据
        this.maxSize = maxSize;
        // 根据 maxSize 创建一个队列
        this.queue = new int[maxSize];
        // 初始让队头队尾为 -1
        this.front = -1; // front 指向队头的前一个位置,若为 0 则指向队头那一个位置
        this.rear = -1; // rear 指向队尾的位置
    }

    // 队列判空
    public boolean isEmpty() {
        return front == rear;
    }

    // 队列判满
    public boolean isFull() {
        return rear == maxSize - 1;
    }

    // 入队
    public void pushQueue(int data) {
        // 先判断队列是否满了
        if (isFull()) {
            System.out.println("队列已满,不能添加数据了");
            return;
        }
        rear++; // 移动队尾指针,指向后一个空的位置
        queue[rear] = data; // 向该空的位置添加数据,此时 rear 依旧指向队尾最后一个数据
    }

    // 出队
    public int popQueue() {
        // 先判断队列是否为空
        if (isEmpty()) {
            throw new RuntimeException("队列为空,不能获取数据");
        }
        // 此时 front 指向后一个位置,该位置是要被取出数据的位置
        // 数据取出后相当于队列移除该数据了,所以 front 仍然指向队头位置的前一个位置
        front++;
        return queue[front];
    }

    // 打印队列
    public void showQueue() {
        if (isEmpty()) {
            System.out.println("队列为空...");
            return;
        }
        System.out.println("队列元素为:");
        for (int i = front + 1; i <= rear; i++) {
            System.out.printf(queue[i] + "\t");
        }
        System.out.println();
    }
}

数组模拟环形队列

在上一个实现中,数组使用一次就不能再使用,没有达到复用效果,造成空间的浪费。

思路分析

Java 队列_第3张图片

代码实现

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        // 创建一个队列
        // 因为有一个位置是用于判断队列是否为满,即不存储具体数据,所以实际队列容量为 4-1=3
        CircleArrayQueue queue = new CircleArrayQueue(4);
        int select;
        Scanner scanner = new Scanner(System.in);
        boolean loop = true;

        while (loop) {
            System.out.println("\n----------队列操作菜单-----------");
            System.out.println("1、查看队列");
            System.out.println("2、添加数据到队列");
            System.out.println("3、取出队列元素");
            System.out.println("4、退出菜单");
            System.out.println("请选择:");

            select = scanner.nextInt();
            switch (select) {
                case 1: {
                    queue.showQueue();
                    break;
                }
                case 2: {
                    System.out.println("请输入要添加的数据(数字类型):");
                    int data = scanner.nextInt();
                    queue.pushQueue(data);
                    break;
                }
                case 3: {
                    try {
                        int data = queue.popQueue();
                        System.out.println("队头元素为:" + data);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                }
                case 4: {
                    loop = false;
                    break;
                }
            }
        }
        scanner.close();
    }
}

// 用数组模拟环形队列
class CircleArrayQueue {
    private int maxSize; // 队列的最大容量
    // front 指向队列的第一个元素,也就是说 queue[front] 就是队列的第一个元素
    // front 的初始值为 0
    private int front; // 队头指针
    // rear 指向队列的最后一个元素的后一个位置,因为希望空出一个位置作为判断队列是否为满的标志
    // rear 的初始值为 0
    private int rear; // 队尾指针
    private int[] queue; // 队列,用于存储数据,此处用数组模拟

    CircleArrayQueue(int maxSize) {
        // 初始化数据
        this.maxSize = maxSize;
        // 根据 maxSize 创建一个队列
        this.queue = new int[maxSize];
        // 初始让队头队尾为 0,也可以不写,因为成员变量默认值就是为 0
        this.front = 0;
        this.rear = 0;
    }

    // 队列判空
    public boolean isEmpty() {
        return front == rear;
    }

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

    // 入队
    public void pushQueue(int data) {
        // 先判断队列是否满了
        if (isFull()) {
            System.out.println("队列已满,不能添加数据了");
            return;
        }

        // 因为 rear 本身就指向队列最后一个元素的后一个位置,所以可以直接将数据加入
        queue[rear] = data;
        // 将 rear 后移,需要取模,因为可能数组前面是可利用的空间,把 rear 指向前面空的位置
        rear = (rear + 1) % maxSize;
    }

    // 出队
    public int popQueue() {
        // 先判断队列是否为空
        if (isEmpty()) {
            throw new RuntimeException("队列为空,不能获取数据");
        }

        // front 指向队列的第一个元素
        // 先把 front 对应的值用一个临时变量存储
        // 将 front 后移,需要取模
        // 将临时变量返回
        int val = queue[front];
        front = (front + 1) % maxSize;
        return val;
    }

    // 打印队列
    public void showQueue() {
        if (isEmpty()) {
            System.out.println("队列为空...");
            return;
        }
        System.out.println("队列元素为:");
        int size = queueSize();
        for (int i = front; i < front + size; i++) {
            System.out.printf(queue[i % maxSize] + "\t");
        }
        System.out.println();
    }

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

你可能感兴趣的:(数据结构和算法,java,开发语言)