基于链表实现Java 自定义Queue队列

时间:2021-01-22 17:39:48

与栈一样,我们也可以借助单链表来实现队列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)时间内完成。而且,这里同样无需限定队列的最大规模。当然,受单链表结构的限制,我们仍然需要对各种特殊情况(如队空时)专门处理。