【数据结构与算法】环形队列的介绍、用数组实现环形数组

1. 环形队列的基本介绍

队列是一个有序列表,遵循先入先出的原则。可以用数组或链表来实现

而环形队列,通过取模的方式,将数组看做是一个环形的

2. 使用数组实现环形队列

环形队列的变量说明

  • 环形队列有一个最大容量maxSize
  • 队列的输出由head下标来控制,head会随着数据的输出而改变
  • 队列的输入由tail下标来控制,tail会随着数据的输入而改变
  • 队列是否满了,或队列是否为空,由变量flag控制
  • 用一个数组来储存队列的数据

环形队列的方法说明

  • add2ArrayQueue:将数据添加到队列。如果队列未满,则可以添加数据。如果添加完数据后,队列满了则修改flag变量
  • takeFromArrayQueue:从队列获取数据。如果队列不为空,则从队列获取数据。如果获取完数据后,队列为空则修改flag变量
  • showArrayQueue:显示队列的所有数据,但不取出
  • showHead:显示队列的头数据,但不取出

环形队列的实现:

import java.util.Scanner;

public class CircleArrayQueueDemo {

    public static void main(String[] args) {

        // 创建一个环形队列
        CircleArrayQueue circleArrayQueue = new CircleArrayQueue(4);
        // 用于接收用户输入
        char key = ' ';
        Scanner scanner = new Scanner(System.in);
        boolean loop = true;

        // 输出一个菜单
        System.out.println("a(add): 添加数据到队列");
        System.out.println("t(take): 从队列取出数据");
        System.out.println("s(show): 显示队列所有数据");
        System.out.println("h(head): 查看队列头部数据");
        System.out.println("e(exit): 退出程序");
        while (loop) {

            // 接收一个字符
            key = scanner.next().charAt(0);
            switch (key) {
                case 'a':
                    System.out.println("请输出一个数:");
                    int inputData = scanner.nextInt();
                    circleArrayQueue.add2ArrayQueue(inputData);
                    break;
                case 't':
                    try {
                        int resultData = circleArrayQueue.takeFromArrayQueue();
                        System.out.printf("取出的数据是%d\n", resultData);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 's':
                    circleArrayQueue.showArrayQueue();
                    break;
                case 'h':
                    circleArrayQueue.showHead();
                    break;
                case 'e':
                    scanner.close();
                    loop = false;
                    break;
                default:
                    break;
            }
        }
        System.out.println("程序退出");

    }
}


class CircleArrayQueue {
    // 数组的最大容量
    private int maxSize;
    // head指向队列的头部(获取下一个数据的index)
    private int head;
    // tail指向队列的尾部(添加下一个数据的index)
    private int tail;
    // flag = 0表示空,flag = 1表示满
    private int flag;
    // 用数组来实现环形队列
    private int[] arrayQueue;

    public CircleArrayQueue(int maxSize) {
        this.maxSize = maxSize;
        // 初始化head和tail都指向0
        this.head = 0;
        this.tail = 0;
        this.flag = 0;
        this.arrayQueue = new int[this.maxSize];
    }

    // 判断队列是否空
    public boolean isEmpty() {
        // 如果head等于tail,且falg等于0,则表示空了
        return this.head == this.tail && flag == 0;
    }

    // 判断队列是否满
    public boolean isFull() {
        // 如果head等于tail,且flag等于1,则表示满了
        return this.head == this.tail && flag == 1;
    }


    // 添加数据到数组队列
    public void add2ArrayQueue(int data) {
        if (isFull()) {
            System.out.println("队列满了, 不能添加数据了");
            return;
        }
        this.arrayQueue[this.tail] = data;
        // 取模是为了跳转到数组的头部
        this.tail = (this.tail + 1) % this.maxSize;
        // 如果下一个要添加数据的index,和下一个要获取数据的index(还未获取)相等,则表示队列满了
        if (this.tail == this.head) {
            this.flag = 1;
        }

    }

    // 从队列获取数据
    public int takeFromArrayQueue() throws Exception {
        if (isEmpty()) {
            throw new Exception("队列是空的,不能获取数据");
        }

        int data = this.arrayQueue[this.head];
        // 取模是为了跳转到数组的头部
        this.head = (this.head + 1) % maxSize;
        // 如果下一个要获取数据的index,和下一个要添加数据的index(还未添加)相等,则表示队列为空
        if (this.head == this.tail) {
            this.flag = 0;
        }
        return data;
    }

    // 计算当前队列有效数据的个数
    public int size() {
        if (isEmpty()) {
            return 0;
        } else if (isFull()) {
            return this.maxSize;
            // 如果tail在head后,则有效数据个数等于tail - head
        } else if (this.tail > this.head) {
            return this.tail - this.head;
            // 如果tail在head前,则有效数据等于maxSize - head + tail
        } else {
            return this.maxSize - this.head + this.tail;
        }
    }

    // 显示队列的所有数据(并不是取出)
    public void showArrayQueue() {
        if (isEmpty()) {
            System.out.println("队列空的,不能显示数据");
            return;
        }

        // 从head开始遍历,遍历有效数据的个数
        for (int i = this.head; i < this.head + this.size(); i++) {
            System.out.printf("arrayQueue[%d]=%d\n", i % this.maxSize, this.arrayQueue[i % this.maxSize]);
        }
    }


    // 显示队列的head的数据(并不是取出)
    public void showHead() {
        if (isEmpty()) {
            System.out.println("队列空的,不能显示数据");
            return;
        }
        System.out.println(this.arrayQueue[this.head]);
    }
}

运行程序,结果如下:

a(add): 添加数据到队列
t(take): 从队列取出数据
s(show): 显示队列所有数据
h(head): 查看队列头部数据
e(exit): 退出程序
a
请输出一个数:
10
a
请输出一个数:
11
t
取出的数据是10
s
arrayQueue[1]=11
h
11
e
程序退出
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值