环形队列模拟(图解+java代码实现)

图中展示了两种情况下的指针变化(注意两个指针的值一直在递增的,可能会大于size) 

代码实现:(解说见注释)

/**
 * 主类,用于提供主方法
 *
 * @author hanj.cn @outlook.com
 */
public class QueueTest {

    public static void main(String[] args) {

        Queue queue = new Queue(5);
        boolean bool = true;

        while (bool) {
            System.out.print("\n请输入指令:");
            Scanner scanner = new Scanner(System.in);
            String input = scanner.nextLine();

            switch (input) {
                case "f":
                    if (queue.isFull()) {
                        System.out.println("队列已满");
                    } else {
                        System.out.println("队列未满");
                    }
                    break;

                case "i":
                    queue.info();
                    break;

                case "e":
                    if (queue.isEmpty()) {
                        System.out.println("队列为空");
                    } else {
                        System.out.println("队列不为空");
                    }
                    break;

                case "w":
                    queue.getWholeQueue();
                    break;

                case "g":
                    queue.getQueue();
                    break;

                case "a":
                    Scanner scanner1 = new Scanner(System.in);
                    String string = scanner1.nextLine();
                    queue.add(string);
                    break;

                case "q":
                    System.out.println("成功退出~~~");
                    bool = false;
                    break;

                default:
                    System.out.println("输入有误");
                    break;
            }
        }
    }

}

/**
 * 一个用来模拟队列的类
 */
class Queue {

    // 数组大小
    private final int size;
    // 头指针,指向第一个元素的位置,初始化为0
    private int front;
    // 尾指针,指向最后一个元素的下一个位置,初始化为0
    private int rear;
    // 维护的数组
    private final String[] array;

    /**
     * 初始化
     *
     * @param size the size
     */
    public Queue(int size) {

        this.size = size;
        this.array = new String[size];
    }

    /**
     * 判断队列是否为空
     *
     * @return the boolean
     */
    public boolean isEmpty() {
        // 由图可知, rear = front 时,队列为空,注意 front <= rear 是一直成立的,并且 rear - front <= size - 1 也是成立的
        return rear == front;
    }

    /**
     * 判断数组是否已经满了
     *
     * @return the boolean
     */
    public boolean isFull() {
        // 由于我们判断数组是否为空的条件是 rear == front 所以为了区分这两种情况,规定 rear 始终指向最后一个元素的下一个位置,这就导致一个问题,最后一个位置是无法填充元素的,即队列最大可用容量为最大容量减一
        return ((rear + 1) - front) % size == 0;
    }

    /**
     * 添加元素
     *
     * @param string the string
     */
    public void add(String string) {

        if (!isFull()) {
            // 注意此处的 ++rear ,前"++"确保了 rear 指针的位置始终在最后一个元素的后面
            array[((++rear) - 1) % size] = string;
            System.out.printf("添加:%s 成功\n", string);
            return;
        }
        System.out.println("队列已满");
    }

    /**
     * 获取 front 指针指向的数据
     */
    public void getQueue() {

        if (!isEmpty()) {
            // 注意此处的 front++ ,这完成了 front 指针的后移
            System.out.printf("取出:%s\n", array[(front++) % size]);
            return;
        }
        System.out.println("队列为空");
    }

    /**
     * 取出所有有效的数据
     */
    public void getWholeQueue() {

        if (!isEmpty()) {
            System.out.println("全部数据如下:");

            for (int i = front % size; i <= (rear - 1) % size; i++) {

                System.out.printf("%s\t", array[i]);
            }
            System.out.println();
            return;
        }
        System.out.println("队列为空");
    }

    /**
     * 获取此时两个指针的位置
     */
    public void info() {

        System.out.printf("front = %d, rear = %d\n", front, rear);
    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值