java实现循环队列


一、基本概念

    队列是一种先进先出(FIFO)的线性表。循环队列即为队列的顺序表示和实现,其优点主要是入队和出队的时间复杂度均为O(1),这要归功于“循环队列将存储结构的理解由序列型转换为环型”的思维方式,如图1所示。

循环队列

图1 序列型转换为环型的思维方式

    循环队列使用的局限性是其在使用前必须明确和预知队列长度。


二、基本思路

  1. 建立尾标记(c语言中为尾指针)
  2. 设立头标记(c语言中为头指针)
  3. 入队时尾标记加1,出队时头标记加1


三、程序实现

ISequenceQueue.java

package org.linxiupan.algrithm.sequency.queue;

public interface ISequenceQueue<T> {
	public boolean push(T t);
	public T pop();
	public int length();
	public int size();
	public boolean isEmpty();
	public boolean isFull();
}

SequenceQueue.java

package org.linxiupan.algrithm.sequency.queue;

import org.linxiupan.algrithm.Logger;

public class SequenceQueue<T> implements ISequenceQueue<T>{

	Object[] datas;
	int size;
	int front = 0;
	int rear =0;
	
	public SequenceQueue(int size){
		this.size = size;
		this.datas = new Object[size];
	}
	
	public boolean push(T t) {
		if(isFull())return false;
		datas[rear]=t;
		rear=(rear+1)%size;
		return true;
	}

	public T pop() {
		if(isEmpty())return null;
		@SuppressWarnings("unchecked")
		T t = (T) datas[front];
		datas[front]=null;
		front=(front+1)%size;
		return t;
	}
	
	public int length(){
		return (rear-front+size)%size;
	}
	
	public boolean isEmpty(){
		if(rear==front)return true;
		return false;
	}

	public boolean isFull() {
		if((rear+1)%size==front)return true;
		return false;
	}

	public int size() {
		return size;
	}
	
	public static void main(String[] args) {
		SequenceQueue<Integer> o = new SequenceQueue<Integer>(10);
		for(int i=1;i<=30;i++){
			boolean b = o.push(i);
			Logger.log("%d 入队后队列长度为 %d",i,o.length());
			if(i%2==0){
				Integer out=o.pop();
				Logger.log("%d -> 现在的长度是 %d, 出队值=%d",i,o.length(),out);
			}
			if(!b){
				Logger.log("%d 未入队",i);
			}
		}
		for(int i=1;i<=10;i++){
			Integer out=o.pop();
			Logger.log("%d -> 现在的长度是 %d, 出队值=%d",i,o.length(),out);
		}
		Logger.log("");

	}

}

Logger.java

package org.linxiupan.algrithm;

public class Logger {
	public static void log(String format, Object... args){
		System.out.println(String.format(format, args));
	}
	
	public static void log(String log){
		System.out.println(log);
	}
}

三、测试结果

1 入队后队列长度为 1
2 入队后队列长度为 2
2 -> 现在的长度是 1, 出队值=1
3 入队后队列长度为 2
4 入队后队列长度为 3
4 -> 现在的长度是 2, 出队值=2
5 入队后队列长度为 3
6 入队后队列长度为 4
6 -> 现在的长度是 3, 出队值=3
7 入队后队列长度为 4
8 入队后队列长度为 5
8 -> 现在的长度是 4, 出队值=4
9 入队后队列长度为 5
10 入队后队列长度为 6
10 -> 现在的长度是 5, 出队值=5
11 入队后队列长度为 6
12 入队后队列长度为 7
12 -> 现在的长度是 6, 出队值=6
13 入队后队列长度为 7
14 入队后队列长度为 8
14 -> 现在的长度是 7, 出队值=7
15 入队后队列长度为 8
16 入队后队列长度为 9
16 -> 现在的长度是 8, 出队值=8
17 入队后队列长度为 9
18 入队后队列长度为 9
18 -> 现在的长度是 8, 出队值=9
18 未入队
19 入队后队列长度为 9
20 入队后队列长度为 9
20 -> 现在的长度是 8, 出队值=10
20 未入队
21 入队后队列长度为 9
22 入队后队列长度为 9
22 -> 现在的长度是 8, 出队值=11
22 未入队
23 入队后队列长度为 9
24 入队后队列长度为 9
24 -> 现在的长度是 8, 出队值=12
24 未入队
25 入队后队列长度为 9
26 入队后队列长度为 9
26 -> 现在的长度是 8, 出队值=13
26 未入队
27 入队后队列长度为 9
28 入队后队列长度为 9
28 -> 现在的长度是 8, 出队值=14
28 未入队
29 入队后队列长度为 9
30 入队后队列长度为 9
30 -> 现在的长度是 8, 出队值=15
30 未入队
1 -> 现在的长度是 7, 出队值=16
2 -> 现在的长度是 6, 出队值=17
3 -> 现在的长度是 5, 出队值=19
4 -> 现在的长度是 4, 出队值=21
5 -> 现在的长度是 3, 出队值=23
6 -> 现在的长度是 2, 出队值=25
7 -> 现在的长度是 1, 出队值=27
8 -> 现在的长度是 0, 出队值=29
9 -> 现在的长度是 0, 出队值=null
10 -> 现在的长度是 0, 出队值=null

注:在真实应用中,未入队意味着队列已满,此处在一般情况应该一直等待直到入队成功为止。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值