队列与循环队列(数组实现)

队列:FIFO

一、普通队列

问题分析并优化

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

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

二、循环队列

数组得到复用

package com.queue;

import java.util.Scanner;

/**
 * @program: DataStructures
 * @description: 队列(数组)
 * @author: XuDeming
 * @date: 2019-12-27 00:23:55
 **/
public class ArrayQueueDemo {

    public static void main(String[] args) {

        System.out.println("***数组实现队列测试***");

        Scanner scanner = new Scanner(System.in);
        System.out.println("请选择队列种类");
        System.out.println("1:数组队列");
        System.out.println("2:循环数组队列");
        int kind = scanner.nextInt();
        System.out.println("请输入队列长度:");
        int size = scanner.nextInt();

        // 创建队列
        Queue queue = kind == 0 ? new ArrayQueue(size) : new ArrayCircleQueue(size + 1);

        char key = 'e';
        boolean flag = true;

        // 队列操作菜单
        while (flag) {
            System.out.println("***队列操作菜单***");
            System.out.println("s(show): 显示队列");
            System.out.println("l(length): 显示队列长度");
            System.out.println("e(exit): 退出程序");
            System.out.println("a(add): 添加数据到队列");
            System.out.println("g(get): 从队列取出数据");
            System.out.println("h(head): 查看队列头的数据");
            System.out.println("c(clean): 清空队列");

            // 接收一个字符
            key = scanner.next().charAt(0);
            switch (key) {
                case 's':
                    queue.showQueue();
                    break;
                case 'l':
                    System.out.println("队列长度为:" + queue.length());
                    break;
                case 'a':
                    System.out.println("请输入一个数字");
                    int a = scanner.nextInt();
                    queue.addQueue(a);
                    break;
                case 'g':
                    System.out.println("从队列中取出的元素为:" + queue.getQueue());
                    break;
                case 'h':
                    System.out.println("队头元素为:" + queue.getHead());
                    break;
                case 'c':
                    queue.cleanQueue();
                    break;
                case 'e':
                    flag = false;
                    break;
                default:
                    break;
            }
        }
        System.out.println("程序退出~");

    }

}

interface Queue{

    // 入队列
    void addQueue(int a);
    // 出队列
    int getQueue();
    // 显示队列
    void showQueue();
    // 查看对头元素
    int getHead();
    // 清空队列
    void cleanQueue();
    // 获取队列元素个数
    int length();

}

// 使用数组编写一个ArrayQueue类
/**
 * 问题分析并优化
 * 1) 目前数组使用一次就不能用, 没有达到复用的效果
 * 2) 将这个数组使用算法,改进成一个环形的队列 取模:%
 */
class ArrayQueue implements Queue{

    // 容器
    private int[] array;
    // 最大容量
    private int maxSize;
    // 队头
    private int front;
    // 队尾
    private int rear;

    // 构造器
    public ArrayQueue(int maxSize) {
        this.array = new int[maxSize];
        this.maxSize = maxSize;
        this.front = -1;// 指向队头的前一个位置
        this.rear = -1;// 指向队尾位置
    }

    // 判断队满
    public boolean isFull() {
        return rear == maxSize - 1;
    }
    // 判断队空
    public boolean isEmpty() {
        return front == rear;
    }
    // 入队列
    public void addQueue(int a) {
        if (isFull()) {
            System.out.println("队列已满~");
            return;
        }
        array[++rear] = a;
    }
    // 出队列
    public int getQueue() {
        int temp = getHead();
        front++;
        return temp;
    }
    // 显示队列
    public void showQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列已空");
        }
        for (int i = front + 1; i <= rear; i++) {
            System.out.print(array[i] + "\t");
        }
        System.out.println();
    }
    // 查看队头元素
    public int getHead() {
        if (isEmpty()) {
            throw new RuntimeException("队列已空");
        }
        return array[front + 1];
    }
    // 清空队列
    public void cleanQueue() {
        front = rear = -1;
    }
    // 队列长度
    public int length() {
        return rear - front;
    }

}

// 使用数组编写一个ArrayCircleQueue类
class ArrayCircleQueue implements Queue{

    // 容器
    private int[] array;
    // 最大容量 空出一个位置作为约定 实际最大容量maxSize-1
    private int maxSize;
    // 队头
    private int front;
    // 队尾
    private int rear;

    // 构造器
    public ArrayCircleQueue(int maxSize) {
        this.array = new int[maxSize];
        this.maxSize = maxSize;
        this.front = 0;// 指向队头位置
        this.rear = 0;// 指向队尾元素后一个位置
    }

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

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

    // 入队列
    public void addQueue(int a) {
        if (isFull()) {
            System.out.println("队列已满~");
            return;
        }
        array[rear] = a;
        rear = (rear + 1) % maxSize;
    }

    // 出队列
    public int getQueue() {
        int temp = getHead();
        front = (front + 1) % maxSize;
        return temp;
    }

    // 显示队列
    public void showQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列已空");
        }
        int key = front;
        for (int i = 0; i < length(); i++){
            System.out.print(array[key] + "\t");
            key = (key + 1) % maxSize;
        }
        System.out.println();
    }

    // 查看队头元素
    public int getHead() {
        if (isEmpty()) {
            throw new RuntimeException("队列已空");
        }
        return array[front];
    }

    // 清空队列
    public void cleanQueue() {
        front = rear = 0;
    }

    // 队列长度
    public int length() {
        return (rear + maxSize - front) % maxSize;
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值