循环队列(java演示)在不牺牲一个空间的情况下,同时不采用求模运算,如何实现,并且提高性能

package com.data_struct.queue;

public class circle_queue
{
    public static void main(String[] args)
    {
        long startime = System.currentTimeMillis();
        System.out.println(startime);
        //1.第一种算法实现
        circle_queue1 cq = new circle_queue1(5);
        cq.inqueue(1);
        cq.inqueue(1);
        System.out.println(cq.queueLength());//求长度
        cq.inqueue(1);
        cq.inqueue(1);
        System.out.println(cq.queueLength());
        cq.inqueue(1);
        System.out.println(cq.queueLength());


        //出队
        cq.outqueue();
        cq.outqueue();
        System.out.println(cq.queueLength());
        cq.outqueue();
        cq.outqueue();
        cq.inqueue(1);

        long endtime = System.currentTimeMillis();
        System.out.println(endtime);
        System.out.println(endtime - startime);
        //第二种算法实现
    }
}

class circle_queue1//顺序队列,第一种算法
{
    private int maxsize;
    private int queue[];
    private int front = 0;
    private int rear = 0;
    private int sign = 3;//0是入队操作,1是出队操作。
    // 因为队满和队空时都是front==rear,因此通过区分上一次操作时入队操作还是出队操作来区分是队满还是

    public circle_queue1(int maxsize)//创建目标大小数组
    {
        this.maxsize = maxsize;

        queue = new int[this.maxsize];

    }

    public void inqueue(int value)//入队操作
    {
        if (this.isFull())
            return;
        sign = 0;
        queue[rear] = value;
//        rear=(rear+1)%maxsize;//取模运算,如果满则归0,逻辑上转换成环形数组。
        rear += 1;
        if (rear == maxsize)
            rear = 0;
//        traverse();
    }

    public void outqueue()//出队
    {
        if (this.isEmpty())
            return;
        sign = 1;
        queue[front] = 0;
//        front=(front+1)%maxsize;
        front += 1;
        if (front == maxsize)
            front = 0;
//        traverse();
    }

    public boolean isEmpty()//判断是否为空
    {
        if (sign == 1 && rear == front)
        {
            System.out.println("队列空");
            return true;
        }
        return false;

    }


    public boolean isFull()//判断是否队列是否满

    {
        if (sign == 0 && rear == front)//rear和front相等有两种情况,
        // 要么为空要么为满,因此用一个标志来决定是满还是空,
        {
            System.out.println("队列满");
            return true;
        }
        return false;
    }

    public void traverse()//遍历
    {
        for (int i = 0; i < maxsize; i++)
        {
            System.out.print(queue[i] + ",");
        }
        System.out.print("\n");
    }

    public int queueLength()//求元素个数
    {
        if (front > rear)//如果rear在front前面,
            // 则应该加上前面的maxsize
            return maxsize - front + rear;
        else if (sign == 0 && rear == front)
            return maxsize;
        else if (sign == 1 && rear == front)
            return 0;
        return rear - front;//如果rear在front后面,则直接相减

//        return (rear-front+maxsize)%maxsize;
//        只适用于牺牲一个空间的算法
    }
}


我们大部分在采用牺牲一个空间和求模运算的环形队列算法,那如何不牺牲一个空间和不采用求模运算呢。

我们通过判断当rear和front达到maxsize时,将它变成0,也可以到达循环的目的。

rear += 1;

if (rear == maxsize)

rear = 0;

这种算法无论数组大小,都是通过判断是否达到maxsize,而求模运算,数组数值越大,求模运算需要的时间越多,因此采用if语句性能更高。

另外通过sign信号值来区分前一步操作时入队操作还是出队操作,区分是队满还是队空。因为队满和队空时,front==rear,。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值