day8-Java(循环列表)

循环队列

一、关于循环队列

首先要确定的是,循环队列与一般队列相同,仍然是基于数组实现的,使用一组地址连续的存储单元依次存放队头到队尾的元素。通俗来说,循环队列可看作单向队列拉成一个环,如下图所示:
在这里插入图片描述

在普通顺序队列中,入队操作就是先将尾指针tail右移一个单位,然后将元素值赋值给tail单位。出队时,则是头指针head后移一个单位。像这样进行了一定数量的入队和出队操作后,可能会出现“假溢出”现象,具体是:尾指针tail已指到数组的最后的一个元素(Tail==MaxLen-1),此时数组的前面部分可能还有很多闲置空间,即这种溢出并非是真的没有可用的存储空间,故称这种溢出现象为“假溢出”。为了解决这个问题,循环列表应运而生。

二、循环队列的实现

在循环队列中,入队和出队操作可看做头指针和尾指针相互追赶,当Tail追到Head就表示队列已经满了,当Head追上Tail就表示队列已经空了。
实现循环队列最关键的部分是确定队列何时为空何时满。循环队列满的判断条件与非循环队列不同,代码如下:

if ((tail + 1) % TOTAL_SPACE == head) {
			System.out.println("Queue full.");
			return;
		} // Of if

循环队列空的判断条件与非循环队列一样,代码如下:

if (head == tail) {
			System.out.println("No element in the queue");
			return -1;
		} // Of if

在循环意义下,入队和出队时头指针和尾指针的+1运算通常用求模运算来实现,代码如下:

data[tail % TOTAL_SPACE] = paraValue;
tail++;

int resultValue = data[head % TOTAL_SPACE];
head++;

三、代码与数据测试

package datastructure.queue;

/**
 * Circle int queue
 *
 * @auther Weijie Pu weijiepu@163.com.
 */
public class CircleIntQueue {

	/**
	 * The total space. One space can never be used.
	 */
	public static final int TOTAL_SPACE = 10;

	/**
	 * The data.
	 */
	int[] data;

	/**
	 * The index for calculating the head. The actual head is head % TOTAL_SPACE.
	 */
	int head;

	/**
	 * The index for calculating the tail;
	 */
	int tail;

	/**
	 * The constructor
	 */
	public CircleIntQueue() {
		data = new int[TOTAL_SPACE];
		head = 0;
		tail = 0;
	} // Of the first constructor

	/**
	 ********************
	 * Enqueue.
	 *
	 * @param paraValue
	 *            The value of the new node.
	 ********************
	 */
	public void enqueue(int paraValue) {
		if ((tail + 1) % TOTAL_SPACE == head) {
			System.out.println("Queue full.");
			return;
		} // Of if

		data[tail % TOTAL_SPACE] = paraValue;
		tail++;
	} // Of enqueue

	/**
	 ********************
	 * Dequeue.
	 *
	 * @return The value at the head.
	 ********************
	 */
	public int dequeue() {
		if (head == tail) {
			System.out.println("No element in the queue");
			return -1;
		} // Of if

		int resultValue = data[head % TOTAL_SPACE];

		head++;

		return resultValue;
	} // Of dequeue

	/**
	 ***********************
	 * Overrides the method claimed in Object, the superclass of any class.
	 ***********************
	 */
	public String toString() {
		String resultString = "";

		if (head == tail) {
			return "empty";
		} // Of if

		for (int i = head; i < tail; i++) {
			resultString += data[i % TOTAL_SPACE] + ", ";
		} // Of for i

		return resultString;
	} // Of toString

	/**
	 ********************
	 * The entrance of the program.
	 *
	 * @param args
	 *            Not used now.
	 ********************
	 */
	public static void main(String args[]) {
		CircleIntQueue tempQueue = new CircleIntQueue();
		System.out.println("Initialized, the list is: " + tempQueue.toString());

		for (int i = 0; i < 5; i++) {
			tempQueue.enqueue(i + 1);
		} // Of for i
		System.out.println("Enqueue, the queue is: " + tempQueue.toString());

		int tempValue = tempQueue.dequeue();
		System.out.println("Dequeue " + tempValue + ", the queue is: " + tempQueue.toString());

		for (int i = 0; i < 6; i++) {
			tempQueue.enqueue(i + 10);
			System.out.println("Enqueue, the queue is: " + tempQueue.toString());
		} // Of for 1
		
		for (int i = 0; i < 3; i++) {
			tempValue = tempQueue.dequeue();
			System.out.println("Dequeue " + tempValue + ", the queue is: " + tempQueue.toString());
		} // Of for i
		
		for (int i = 0; i < 6; i++) {
			tempQueue.enqueue(i + 100);
			System.out.println("Enqueue, the queue is: " + tempQueue.toString());
		} // Of for i
	} // Of main

} // Of CircleIntQueue

运行结果:
在这里插入图片描述

总结

循环队列是解决假溢出的问题,通常把一维数组看成收尾相接。在老师的这段代码中,还有个需要注意的点,当判断队列为满时,这个队列实际存储长度为MaxLength-1,因为这里尾指针指向的是最后一个元素的下一个地址,即Tail指针指向的位置实际上是没有存储数据的,所以这里是牺牲一个存储空间来实现队满判断。

今日代码量:132
累积:1638

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值