数据结构学习(循环队列)

1. 尾索引的下一个为头索引时表示队列满,即将队列容量空出一个作为约定
2. 这个在做判断队列满的时候需要注意 (rear + 1) % maxSize == front [满]
rear == front [空]

package cn.imut;
//循环队列
import java.util.Scanner;

public class CircleArrayQueueDemo {
    public static void main(String[] args) {
        System.out.println("测试数组模拟循环队列的案例");
        //创建一个队列
        CircleArray circlequeue = new CircleArray(4);       //这里设置4,其队列的有效数据最大是3
        var key = ‘ ‘;         //接收用户输入
        Scanner sc = new Scanner(System.in);
        boolean loop = true;
        //输出一个菜单
        while(loop){
            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 = sc.next().charAt(0);          //接收一个字符
            switch (key){
                case ‘s‘:
                    circlequeue.showQueue();
                    break;
                case ‘a‘:
                    System.out.println("输入一个数");
                    int value = sc.nextInt();
                    circlequeue.addQueue(value);
                    break;
                case ‘g‘:
                    try{
                        int res = circlequeue.getQueue();
                        System.out.printf("取出的数据是%d\n", res);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case ‘h‘:
                    try{
                        int res = circlequeue.headQueue();
                        System.out.printf("队列头的数据是%d\n", res);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case ‘e‘:
                    sc.close();
                    loop = false;
                    break;
                default:
                    break;
            }
        }
        System.out.println("程序退出!");
    }
}

class CircleArray{
    private int maxSize;        //表示数组最大容量
    //front指向队列的第一个元素,也就是说arr[front]就是队列的第一个元素,front的初始值=0
    private int front;          //队列头
    //rear指向队列的最后一个元素的后一个位置,希望腾出一个空间作为约定,rear的初始值=0
    private int rear;           //队列尾
    private int[] arr;          //该数组用于存储数据,模拟队列
    /*
     *           取数据时front改变,加数据时rear改变
     *           在循环队列中,为了判断队列满和队列空的情况,对队列少用一个元素空间,使头指针指向队头元素的前一个位置,当尾指针等于该位置时就表示队满。
     */
    //创建队列的构造器
    public CircleArray(int arrMaxSize){
        maxSize = arrMaxSize;           //初始化为0,不用重新赋值
        arr = new int[maxSize];
    }

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

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

    //添加数据到队列
    public void addQueue(int n){
        //判断队列是否已满
        if(isFull()){
            System.out.println("队列已满!");
            return;
        }
        //直接将数据加入即可
        arr[rear] = n;
        //将rear后移,这里必须考虑取模 (防止数组越界)
        rear = (rear + 1) % maxSize;
    }

    //获取队列的数据,出队列
    public int getQueue(){
        //判断队列是否为空
        if(isEmpty()){
            //通过抛出异常
            throw new RuntimeException("队列为空,不能取数据");
        }
        //这里需要分析front是指向队列的第一个元素
        //1.先把front对应的值保存到一个临时变量
        //2.将front后移,考虑取模
        //3.将临时保存的变量返回
        int value = arr[front];
        front = (front + 1) % maxSize;
        return value;
    }

    //显示队列的所有数据
    public void showQueue(){
        //遍历
        if(isEmpty()){
            System.out.println("队列为空,没有数据...");
            return;
        }
        //思路:从front开始遍历
        for(int i = front; i < front + size(); i++){
            System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]);
        }
    }

    //求出当前队列有效数据个数
    public int size(){
        //eg: rear = 1  front = 0  maxSize = 3
        //(尾 + 最大值 - 头) % 最大值
        return (rear + maxSize - front) % maxSize;
    }

    //显示队列的头数据(不是取数据)
    public int headQueue(){
        //判断
        if(isEmpty()){
            throw new RuntimeException("队列为空,没有数据...");
        }
        return arr[front];
    }
}

原文地址:https://www.cnblogs.com/yfyyy/p/12019268.html

时间: 2024-10-27 13:58:20

数据结构学习(循环队列)的相关文章

基本数据结构,循环队列的顺序实现。

队列是一种先进先出的数据结构,这里用顺序结构将其实现. 1.首先用结构体定义一个队列,front指向队首元素的前面一位,real指向队尾元素. 1 //队列的结构定义 2 #define MAX 6 3 typedef struct { 4 int front,real; 5 int data[MAX]; 6 }queue; 2.创建一个循环队列,初始化令front=real=0,因为当队列满时也有front=real,此时无法判断队满:所以我们弃置一个元素位不用,其位置随机,所以队列的实际最大

数据结构之循环队列c语言实现

    队列是一种先入先出的结构,数据从队列头出,队尾进.在linux内核中进程调度,打印缓冲区都有用到队列.     队列有多种实现方式,可以用链表,也可以用数组.这里用数组来实现一个简单的循环队列.首先创建一个大小为8的队列如下,队列头尾指针指向同一块内存,          当从队列尾部插入一个数据后变成下面的情形,为了便于处理,这里始终会浪费一个空间 继续插入数据,直到出现以下情形,表示队列满了, 接下来看一下出队的情形,从队列头出队3个元素, 再添加三个元素后队列又变成满的了, 在上面

数据结构--顺序循环队列和链式队列

第一部分:顺序循环队列的实现 1 //循环队列的实现 2 #define OK 1 3 #define MAXSIZE_Q 10 4 //#define OVERFLOW -2 5 #define ERROR 0 6 7 typedef int Status; 8 typedef int QElemtype; 9 10 typedef struct{ 11 QElemtype *base; //初始化的动态分配存储空间 12 int front; //队头指针 13 int rear; //队尾

数据结构:循环队列(C语言实现)

生活中有非常多队列的影子,比方打饭排队,买火车票排队问题等,能够说与时间相关的问题,一般都会涉及到队列问题:从生活中,能够抽象出队列的概念,队列就是一个能够实现"先进先出"的存储结构.队列分为链式队列和静态队列:静态队列一般用数组来实现,但此时的队列必须是循环队列,否则会造成巨大的内存浪费:链式队列是用链表来实现队列的.这里讲的是循环队列,首先我们必须明确以下几个问题 一.循环队列的基础知识 1.循环队列须要几个參数来确定 循环队列须要2个參数,front和rear 2.循环队列各个參

数据结构之循环队列(C++版)

#include <iostream>#include <stdlib.h>#include <string>#define MAXLISTSIZE 100 //预设的存储空间最大容量 using namespace std;typedef string ElemType;typedef struct{ ElemType *elem; //存储空间基址 int rear; //队尾指针 int front; //队头指针 int queuesize; //允许的最大存储

数据结构:循环队列

数组表示的问题 对于队列最好的方法是使用链表实现,因为对于数组来说,队列可能会出现下面这种情况: 如图所示,不可以继续添加元素,否则会造成数组越界而遭致程序出错.然而此时又不应该扩充数组,因为还有大量实际空间未被占用. 此时我们应该如何解决这个问题呢?我们将其实现为循环队列. 理解循环队列 何谓循环队列?首先我们要说明的是循环队列仍然是基于数组实现的.但是为了形象化的说明问题,我们如下图所示 1.图中有两个指针(其实就是两个整数型变量,因为在这里有指示作用,所以这里理解为指针)front.rea

【 数据结构 】循环队列

队列是先进先出(first in first out)的线性表,简称 FIFO. 假设循环队列: 队头:front 队尾:rear 最大尺寸:queue size 队列满:(rear + 1)% queue size == front 通用队列长度计算: (rear - front + queue size)% queue size 存储结构代码示例 typedef int QElemType; /* 队列内数据的类型 */ /* 循环队列的顺序存储结构 */ typedef struct {

【数据结构】循环队列的实现(c++)

头文件: #pragma once #include <iostream> #include <assert.h> using namespace std; template<class Type> class CQueue { public: CQueue(size_t sz = INIT_SZ); ~CQueue(); public: bool full()const; bool empty()const; void show()const; bool push(c

[数据结构学习]单调队列

单调队列,即内部元素相对于比较器有序的队列,可以方便的查询序列中某个连续区间内的最大/最小值 也能在状态转移时优化决策以降低时间复杂度.(嗯,这句是OI-Wiki上说的,作为蒟蒻qwq我并不知道如何优化dp) 比如我们想知道一个长为n的数字序列中每连续k个数中最小的那个数 如果暴力求解的话,遍历从1~n-k+1,复杂度O(n*k),而且需要将每个子序列中的值与其他值进行比较,是比较慢的=-= 对于这个问题就可以维护一个递减的单调队列,同时注意队列中的数字区间不要超过k 维护的方法: 每读入序列中