0
点赞
收藏
分享

微信扫一扫

Day07——队列、循环队列

清冷的蓝天天 2022-04-06 阅读 75
javaeclipse

队列

队列:允许在一端进行插入,在另一端进行删除。允许插入的一端称为队尾,允许删除的一端称为队头。顾名思义,队列需要两个变量来记录队尾和队首的位置,方便进行入队和出队操作。

队列的特点:先进先出

链队列

需要注意的是:出队前需要确定队列里面是否有元素,并且出队后要检查是否队列为空,如果为空,还需要重新赋值tailNode为headerNode,避免tailNode指向null,再次添加队列元素时报错。

package day07;

public class LinkedQueue {

	class Node {
		/**
		 * The data.
		 */
		int data;

		/**
		 * The reference to the next node.
		 */
		Node nextNode;

		/**
		 * The constructor.
		 * 
		 * @param paraValue The data.
		 */
		public Node(int paraValue) {
			data = paraValue;
			nextNode = null;
		}// Of the constructor
	}// Of class Node

	/**
	 * The header of the queue.
	 */
	Node headerNode;

	/**
	 * The tail of the queue.
	 */
	Node tailNode;

	/**
	 * Construct an empty sequential list.
	 */
	public LinkedQueue() {
		headerNode = new Node(-1);

		tailNode = headerNode;
	}// Of the first constructor.

	/**
	 * Enqueue.
	 * 
	 * @param paraValue The value of the new code.
	 */
	public void enqueue(int paraValue) {
		Node tempNode = new Node(paraValue);
		tailNode.nextNode = tempNode;
		tailNode = tempNode;
	}// Of enqueue

	public int dequeue() {
		if (headerNode == tailNode) {
			System.out.println("No element in the queue");
			return -1;
		} // Of if

		int resultValue = headerNode.nextNode.data;

		headerNode.nextNode = headerNode.nextNode.nextNode;

		// The queue becomes empty.
		if (headerNode.nextNode == null) {
			tailNode = headerNode;
		} // Of if

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

		if (headerNode.nextNode == null) {
			return "empty";
		} // Of if

		Node tempNode = headerNode.nextNode;
		while (tempNode != null) {
			resultString += tempNode.data + ", ";
			tempNode = tempNode.nextNode;
		} // Of while

		return resultString;
	}// Of toString

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

		for (int i = 0; i < 5; i++) {
			tempQueue.enqueue(i + 1);
		} // Of for i

		tempQueue.dequeue();
		System.out.println("Enqueue, the queue is: " + tempQueue.toString());

		int tempValue;
		for (int i = 0; i < 3; i++) {
			tempValue = tempQueue.dequeue();
			System.out.println("Looped delete " + tempValue + ", the queue is: " + tempQueue.toString());
		} // Of for i

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

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

循环队列

基于顺序存储的队列,可以提高内存空间的使用率,但为了区分队列为空和满,需要牺牲一个存储空间,当head==tail时,表示为空,(tail+1)%MAX_SPACE==head时,表示队列为满。
int类型的循环队列:

package day07;

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 calculation the head. The actual head is head % TOTAL_SPACE.
	 */
	int head;

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

	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 - 1; i++) {
			resultString += data[i % TOTAL_SPACE] + ", ";
		} // Of for i

		resultString += data[(tail - 1) % TOTAL_SPACE];
		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 i

		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 class

运行结果:
在这里插入图片描述
char类型的循环队列:

package day07;

public class CircleIntQueue {

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

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

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

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

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

	/**
	 * Enqueue.
	 * 
	 * @param paraValue The value of the new node.
	 */
	public void enqueue(char 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 char dequeue() {
		if (head == tail) {
			System.out.println("No element in the queue");
			return '\0';
		} // Of if

		char 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 - 1; i++) {
			resultString += data[i % TOTAL_SPACE] + ", ";
		} // Of for i

		resultString += data[(tail - 1) % TOTAL_SPACE];
		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 (char i = '0'; i < '5'; i++) {
			tempQueue.enqueue(i);
		} // Of for i
		System.out.println("Enqueue, the queue is: " + tempQueue.toString());

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

		for (char i = 'a'; i < 'f'; i++) {
			tempQueue.enqueue(i);
			System.out.println("Enqueue, the queue is: " + tempQueue.toString());
		} // Of for i

		for (int i = 0; i < 3; i++) {
			tempValue = tempQueue.dequeue();
			System.out.println("Dequeue " + tempValue + ", the queue is: " + tempQueue.toString());
		} // Of for i
		for (char i = 'A'; i < 'F'; i++) {
			tempQueue.enqueue(i);
			System.out.println("Enqueue, the queue is: " + tempQueue.toString());
		} // Of for i
	}// Of main
}// Of class

运行结果:
在这里插入图片描述
通过上面两段代码,不难发现重复的代码部分有很多,如果在C语言中,可以使用typedef将不同data类型的CircleIntQueue定义为同一个类,但无奈Java中没有这样的功能。现在我能想到的办法是,在CircleIntQueue的构造函数中设置参数,根据调用者new 一个CircleIntQueue对象时传递的参数来初始化data数据,并把类型保存为实例属性,至于有关类型的方法调用,则通过方法重载实现。

举报

相关推荐

Day07

Java Day07

day07数组

微服务day07

Java学习-Day07

**day07 - Web APIs**

java基础 Day07

面向对象day07

JavaSE learning day07

0 条评论