队列

队列遵循先入先出原则,可用数组或链表实现。单向队列常用于银行排号系统,但只能添加一次数据。环形队列解决了这一问题,通过数组循环使用,形成一个虚拟的环状结构,允许反复添加数据,关键在于理解和处理队列满和空的状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

队列是一个有序列表,可以用数组或链表来实现,遵循先入先出的原则!!!
增加数据是从队列的尾部添加,拿走数据从队列的顶端拿走!!先进来的先出去,需要用两个变量front和rear来记录队列的前后端 front跟着数据输出(取数据)而改变,rear随着数据输入(存数据)而改变
队列可以分为单向队列与环形队列

1.单向队列

使用场景,银行排号系统
判断条件:
1.当rear==maxSize-1时,无法再添加数据。。
2.front(指向队队列头 的前一个位置)初始化=-1
3.rear(指向队列尾部的数据)初始化=-1
想添加数据直接 array[++rear]=num;
想移除数据直接 return array[++front];
这个单向队列有一个问题:添加数据只能够添加一次。想要解决需要用到环形队列!!!

public class ArrayQueueDemo {
    public static void main(String[] args) {
        char key;
        ArrayQueue aq = new ArrayQueue(4);
        Scanner sc = new Scanner(System.in);
        boolean loop=true;
        while (loop){
            //弹出一个菜单
            System.out.println("s:显示队列");
            System.out.println("g:移除数据");
            System.out.println("a:添加数据");
            System.out.println("e:退出数据");
            key=sc.next().charAt(0);
            switch (key){
                case 's':
                    aq.show();
                    break;
                case 'g':
                    int i = aq.get();
                    System.out.printf("取出数据是%d\n",i);
                    break;
                case 'a':
                    int nextInt = sc.nextInt();
                    aq.add(nextInt);
                    break;
                case 'e':
                    sc.close();
                    loop=false;
                    break;
                default:
                    break;
            }
        }
        System.out.println("程序退出");
    }
}
//创建一个队列类
class ArrayQueue{
    private int  front;
    private int rear;
    private int maxSize;
    private int[] array;
    //创建队列的构造器
    public ArrayQueue( int arrmaxSize){
         maxSize=arrmaxSize;
         array=new int[maxSize];
         front=-1;//指向队列头部的前一个元素
         rear=-1;//指向队列末尾数据
    }
    public boolean isFull(){
        return rear==maxSize-1;
    }
    public boolean isEmpty(){
        //true代表队列空,否代表队列不为空
        return front==rear;
    }
    //
    public void add(int num){
        if(isFull()){
            System.out.println("队列满了");
        }
        array[++rear]=num;
    }
    public  int get(){
        if(isEmpty()){
            //抛出一个异常
            throw new RuntimeException("队列空了,不能取数据");
        }
        return array[++front];
    }
    public void  show(){
        if(isEmpty()){
            System.out.println("队列空了");
            return;
        }
        for (int i =front; i <=rear ; i++) {
           System.out.printf("array[%d]=%d\n",i,array[i]);
        }
    }
}

2.环形队列

上面数组出现的问题:数组使用一次就不能使用 解决的方式是将单向队列改造成环形队列围成一个圆,rear最后还会走向front的位置。
思路分析 :
front指向队列的第一个元素初始值为0
rear指向队列最后一个元素的后一个位置,初始值也是0
我们需要留出一个数组空间作为约定,这个空间不会被赋值,但随着数据的添加,这个约定空间会一直发生变化。
由于约定空间的存在当数组长度为5时有效数据仅有4个而不是5个 这一点需要着重注意!!是弄清楚环形队列的核心
限制条件:
队列空时: front= =rear;
队列满时: (rear+1)%maxSize= =front
有效数据个数(rear+maxSize-front)
环形队列添加数据front与rear的值都是会变化的可以循环重复的添加,要注意的点就是约定空间会变化!

class circleArray{
    private int  front;
    private int rear;
    private int maxSize;
    private int[] array;
    //创建队列的构造器
    public circleArray( int arrmaxSize){
        maxSize=arrmaxSize;
        array=new int[maxSize];
        front=0;//指向队列第一个元素
        rear=0;//指向队列最后一个元素的后一个位置
    }
    public boolean isFull(){
        return (rear+1)%maxSize==front;
    }
    public boolean isEmpty(){
        //true代表队列空,否代表队列不为空
        return front==rear;
    }
    //
    public void add(int num){
        if(isFull()){
            System.out.println("队列满了");
            return;
        }
        array[rear]=num;
        rear = (rear + 1) % maxSize;
    }
    public  int get(){
        if(isEmpty()){
            //抛出一个异常
            throw new RuntimeException("队列空了,不能取数据");
        }
        int value=array[front];
        front=(front+1)%maxSize;
        return value;

    }
    public int head(){
        if (isEmpty()){
            throw new RuntimeException("队列为空");
        }
        return  array[front];
    }
    public void  show(){
        if(isEmpty()){
            System.out.println("队列空了");
            return;
        }
        //从front开始遍历,遍历多少个元素即可。 front加上有效元素的个数
        for (int i = front; i <front+(rear+maxSize-front)%maxSize ; i++) {
            System.out.printf("array[%d]=%d\n",i%maxSize,array[i%maxSize]);
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值