与栈一样,我们也可以借助单链表来实现队列ADT。同样地,出于效率方面的考虑,我们将以单链表的首(末)节点作为队列的首(末)节点。这样,可以回避单链表在尾部进行删除操作时效率低下的缺陷。此外,还需要两个实例变量分别指示表的首、末节点。
java代码如下:
QueueList:
package com.list.queue;
import java.util.Arrays;
import com.list.stack.Node;
import com.list.stack.ExceptionStackEmpty;
/**
*
* @author gannyee
*
*/
public class QueueList {
//Declared head node
private static Node head = new Node();
//Declared rear node
private static Node rear = new Node();
//Declared size
private static int size;
//queue list
private static int length;
//Constructor initialize head, rear, size
public QueueList(){
head = rear = null;
size = length = 0;
}
//Get size
public int getSize(){
return size;
}
//Get length
public int length(){
return length;
}
//Is empty
public boolean isEmpty(){
return size == 0;
}
//Enqueue element
public void enqueue(Object element){
Node newNode = new Node(element,head);
if(getSize() == 0){
head = newNode;
rear = newNode;
}
head = newNode;
size ++;
length = size;
}
//Dequeue element
public Object dequeue() throws ExceptionStackEmpty{
if(isEmpty())
throw new ExceptionStackEmpty("Queue is empty!");
Node travelNode = new Node();
travelNode = head;
Object elementRear;
while(travelNode != null){
if(travelNode.getNext() == rear)
break;
travelNode = travelNode.getNext();
}
elementRear = rear.getElement();
rear = travelNode;
size --;
return elementRear;
}
//Get head node but not delete
public Object getHeadNode() throws ExceptionStackEmpty{
if(isEmpty())
throw new ExceptionStackEmpty("Queue is empty!");
return head.getElement();
}
//Travel all node of queue
public void getAllElement(){
Node travelTop;
travelTop = head;
Object[] array = new Object[getSize()];
for(int i = 0;i < array.length;i ++ ){
array[i] = travelTop.getElement();
travelTop = travelTop.getNext();
}
System.out.println("Get all elemnt: " + Arrays.toString(array));
}
}
QueueListTest :
package com.list.queue;
import com.list.stack.ExceptionStackEmpty;
public class QueueListTest {
public static void main(String[] args) throws ExceptionStackEmpty {
// TODO Auto-generated method stub
//Declared QueueList example
QueueList ql = new QueueList();
System.out.println("Size is: " + ql.getSize());
System.out.println("Is empty? " + ql.isEmpty());
ql.enqueue(12);
ql.enqueue(32);
ql.enqueue(35);
ql.enqueue(12);
ql.enqueue(34);
ql.enqueue(45);
ql.enqueue(17);
ql.enqueue(2);
ql.enqueue(15);
System.out.println("Size is: " + ql.getSize());
System.out.println("Is empty? " + ql.isEmpty());
ql.getAllElement();
for(int i = 0;i < ql.length();i ++)
System.out.println(ql.dequeue());
System.out.println("Size is: " + ql.getSize());
System.out.println("Is empty? " + ql.isEmpty());
}
}
测试结果:
Size is: 0
Is empty? true
Size is: 9
Is empty? false
Get all elemnt: [15, 2, 17, 45, 34, 12, 35, 32, 12]
12
32
35
12
34
45
17
2
15
Size is: 0
Is empty? true
与基于单链表实现的栈结构同理,如上实现的各个队列 ADT 方法都可以在 O(1)时间内完成。而且,这里同样无需限定队列的最大规模。当然,受单链表结构的限制,我们仍然需要对各种特殊情况(如队空时)专门处理。