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,。