日撸 Java 三百行: DAY17 链队列

0.主题

今天实现LinkedQueue类,包括一个内部类,以及几个方法。

1.链队列

队列同栈一样,也是一种受限的表结构,它只能在表的一端插入结点,在另一端删除结点,这两个操作分别被称作入队出队。队列的特性是FIFO,即先进先出。所谓链队列,就是指存储方式为链式存储的队列。

2.程序

1.实例域
LinkedQueue类含有几个实例域,包括一个内部类,一个头结点引用和一个尾结点引用。
内部类包含一个用于存储数据的int型变量,一个用于链接下一个结点的引用和一个构造器,它定义了链表的结点结构。
头、尾结点的引用是为了方便进行入队和出队操作。

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

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

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

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

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

2.构造器
构造器用于初始化一个空队列。

	/**
	 *****************
	 * Constructor an empty sequential list.
	 *****************
	 */
	public LinkedQueue() {
		header = new Node(-1);
		// header.next = null;

		tail = header;
	} // Of the first constructor

3.enqueue
enqueue是队列最常用的操作之一,它在队尾插入一个新的结点。

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

时间复杂度 O ( 1 ) O(1) O(1),因为有尾结点引用,可以直接定位到尾部进行插入

4.dequeue
dequeue也是队列的常用操作,它将队头结点出队,并将该节点的值返回。值得注意的是,出队之前需要先判断是否队空,若已经队空,那么是不能出队的。

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

		int resultValue = header.next.data;

		header.next = header.next.next;

		// The queue becomes empty.
		if (header.next == null) {
			tail = header;
		} // Of if

		return resultValue;
	} // Of dequeue

时间复杂度 O ( 1 ) O(1) O(1)

5.toString
toString将队列中的元素转为其对应的字符串形式。

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

		if (header.next == null) {
			return "empty";
		} // Of if

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

		return resultString;
	} // Of toString

时间复杂度 O ( n ) O(n) O(n),因为要遍历整个队列

6.测试
测试代码如下

	/**
	 *****************
	 * 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
		System.out.println("Enqueue, the queue is: " + tempQueue.toString());

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

		int tempValue;
		for (int i = 0; i < 5; i++) {
			tempValue = tempQueue.dequeue();
			System.out.println("Looped delete " + tempValue + ", the new 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

执行结果如下
日撸 Java 三百行: DAY17 链队列_第1张图片

3.体会

  1. 链队列出队时需要考虑是否队空
  2. 当队列已空的时候,要把tail重新指向header
  3. toString方法会多打印一个逗号,如果将while里的判断条件改一下,对最后一个结点单独处理,就不会这样了,如下所示
		if (header.next == null) {
			return "empty";
		} // Of if

		Node tempNode = header.next;
		while (tempNode != null && tempNode.next != null) {
			resultString += tempNode.data + ", ";
			tempNode = tempNode.next;
		} // Of while
		
		resultString += tempNode.data;

执行结果如下:
日撸 Java 三百行: DAY17 链队列_第2张图片
可以看到,这样就不会在末尾多一个逗号了。

你可能感兴趣的:(java)