数组模拟队列和循环队列(java实现)

一.普通队列      

 首先先用数组模拟一下简单的队列。对于队列,有4个元素,一个头head,一个尾tail,一个队列的最大容量maxSize,还有一个数组int[] 模拟队列。队列的主要操作有1.向队列中添加数据;2.展示整个队列中的数据;3.取出队列的第一个数据;4.得到队列的第一个数据,不取出,只展示;5.判断队列是否为空(head == tail);6.判断队列是否已满(tail == maxSize -1)。

因为队列的输出、输入是分别从前后端来处理,因此需要两个变量 head及 tail 分别记录队列前后端的下标,head会随着数据的输出而改变,tail会随着数据的输入而改变。

代码如下:

队列

class Queue{
    private int head;// 队列头
    private int tail;// 队列尾
    private int maxSize;// 队列的最大容量
    private int[] queue;// 存放数据,模拟队列

    public Queue(int maxSize){
        this.maxSize = maxSize;
        queue = new int[maxSize];
        head = -1; // 指向队列头部,分析出 front 是指向队列头的前一个位置.
        tail = -1; // 指向队列尾,指向队列尾的数据(即就是队列最后一个数据)
    }

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

    // 判断队列是否为空
    public boolean isEmpty(){
        return tail == head;
    }

    // 添加数据到队列中
    public void addQueue(int value){
        if(isFull()){
            System.out.println("队列已满,无法添加数据");
            return ;
        }
        tail = tail+1;
        queue[tail] = value;
    }

    // 取出第一条数据
    public int getQueue(){
        if(isEmpty()){
            throw new RuntimeException("队列为空,无法取出数据");
        }
        head = head+1;
        return queue[head];
    }

    // 展示队列中的数据
    public void showQueue(){
        if(isEmpty()){
            System.out.println("队列为空,无法取出数据");
            return;
        }
        for(int i=0;i<queue.length;i++){
            System.out.println(queue[i]+" ");
        }
    }

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

测试代码

package com.an.struct.queue;
import java.util.Scanner;
/**
 * 数组模拟队列
 * @author AN
 * @create 2020-08-04 16:51
 */
public class ArrQueue {
    public static void main(String[] args) {
        Queue queue = new Queue(3);
        char key = ' ';
        Scanner scanner = new Scanner(System.in);
        boolean flag = true;
        while(flag){
            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):查看队列头数据");
            key = scanner.next().charAt(0);
            switch (key){
                case 's':
                    queue.showQueue();
                    break;
                case 'e':
                    flag = false;
                    break;
                case 'a':
                    System.out.println("输出一个数");
                    int value = scanner.nextInt();
                    queue.addQueue(value);
                    break;
                case 'g':
                    try {
                        int value1 = queue.getQueue();
                        System.out.println("取出的数据为:"+value1);
                        break;
                    }catch (Exception e){
                        System.out.println(e.getMessage());
                    }
                case 'h':
                    try {
                        int headValue = queue.showHead();
                        System.out.println("取出的头结点的数据为:"+headValue);
                        break;
                    }catch (Exception e){
                        System.out.println(e.getMessage());
                    }
            }
        }
    }
}

二.循环队列

对于普通的队列来说,使用一次就不能再次使用,没有达到复用的效果。对这个数组使用算法,改进这个队列,成为一个环形队列。对于环形队列,和普通队列一样,也有4个元素。但是不一样的是

1.head不再指向队列头的前一个元素,应该指向队列的第一个元素,所以head初始值为head=0;

2.tail指向队列中最后一个元素的后一个位置,因为希望空出一个位置作为约定,所以队列中会空出一个位置,当maxSize为4时,队列中最大的数量为3。tail的初始值为0;

3.当队列满的时候,(tail+1)%maxSize == head;

4.当队列为空时,tail == head,和之前一样;

5.队列中的有效数据的格式为 (tail+maxSize-head)%maxSize

6.修改以下,就构成了循环队列

循环队列

// 环形队列
class CircleQueue{
    private int head;
    private int tail;
    private int maxSize;
    private int[] queue;

    public CircleQueue(int maxSize){
        head = 0;
        tail = 0;
        this.maxSize = maxSize;
        queue = new int[maxSize];
    }

    // 判断队列是否满
    public boolean isFull(){
        return (tail+1)%maxSize == head;
    }

    // 判断队列是否为空
    public boolean isEmpty(){
        return tail == head;
    }

    // 添加数据到队列中
    public void addQueue(int value){
        if(isFull()){
            System.out.println("队列已满,无法添加数据");
            return ;
        }
        queue[tail] = value;
        tail = (tail+1)%maxSize;
    }

    // 取出第一条数据
    public int getQueue(){
        if(isEmpty()){
            throw new RuntimeException("队列为空,无法取出数据");
        }
        int tmp = queue[head];
        head = (head+1)%maxSize;
        return tmp;
    }

    // 展示队列中的数据
    public void showQueue(){
        if(isEmpty()){
            System.out.println("队列为空,无法取出数据");
            return;
        }
        for(int i=head;i<head+queueSize();i++){
            System.out.println(queue[i % maxSize]+" ");
        }
    }

    // 找出队列中的个数
    public int queueSize(){
        return (tail+maxSize-head)%maxSize;
    }

    // 显示头结点的数据
    public int showHead(){
        if(isEmpty()){
            throw new RuntimeException("队列为空");
        }
        return queue[head];
    }
}

测试循环队列

package com.an.struct.queue;

import java.util.Scanner;

/**
 * 数组模拟环形队列
 *
 * @author AN
 * @create 2020-08-05 14:53
 */
public class CircleArrayQueue {
    public static void main(String[] args) {
        CircleQueue queue = new CircleQueue(4);
        char key = ' ';
        Scanner scanner = new Scanner(System.in);
        boolean flag = true;
        while(flag){
            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):查看队列头数据");
            key = scanner.next().charAt(0);
            switch (key){
                case 's':
                    queue.showQueue();
                    break;
                case 'e':
                    flag = false;
                    break;
                case 'a':
                    System.out.println("输出一个数");
                    int value = scanner.nextInt();
                    queue.addQueue(value);
                    break;
                case 'g':
                    try {
                        int value1 = queue.getQueue();
                        System.out.println("取出的数据为:"+value1);
                        break;
                    }catch (Exception e){
                        System.out.println(e.getMessage());
                    }
                case 'h':
                    try {
                        int headValue = queue.showHead();
                        System.out.println("取出的头结点的数据为:"+headValue);
                        break;
                    }catch (Exception e){
                        System.out.println(e.getMessage());
                    }
            }
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值