除了可以通过一维数组,单链表实现queue队列,还可以通过双链表实现queue队列。
在基于NLNode类实现双向链表的时候,为了使编程更加简洁,通常我们都要在最前端和最后端各设置一个哑元节点( Dummy node )。这两个节点分别称作头节点( Header node )和尾节点( Trailer node) ㈠,起哨兵( Sentinel)的作用。也就是说,它们并不存储任何实质的数据对象,头(尾)节点的next( prev)引用指向首(末)节点,而prev(next)引用为空。如此构成的双向链表结构,如下代码示:
Java代码:
DoubleNode 类:
package com.doub.list;
/** * * @author gannyee * */
public class DoubleNode {
//Declared element
private Object element;
//Declared prior
private DoubleNode prior;
//Declared next
private DoubleNode next;
//Constructor
public DoubleNode(){
this(null,null,null);
}
public DoubleNode(DoubleNode prior,Object element, DoubleNode next){
this.prior = prior;
this.element = element;
this.next = next;
}
//Get element
public Object getElement() {
return element;
}
//Set element
public void setElement(Object element) {
this.element = element;
}
//Get prior
public DoubleNode getPrior() {
return prior;
}
//Set prior
public void setPrior(DoubleNode prior) {
this.prior = prior;
}
//Get next
public DoubleNode getNext() {
return next;
}
//Set next
public void setNext(DoubleNode next) {
this.next = next;
}
}
DoubleListQueue 类:
package com.doub.list;
import java.util.Arrays;
import com.queue.ExceptionQueueEmpty;
public class DoubleListQueue {
// Declared head
private static DoubleNode head;
// Declared rear
private static DoubleNode rear;
// Declared size;
private static int size;
//Declared length
private static int length;
// Constructor
public DoubleListQueue() {
//initialize
head = new DoubleNode();
rear = new DoubleNode();
head.setNext(rear);
head.setPrior(null);
rear.setNext(null);
rear.setPrior(head);
this.size = this.length = 0;
}
// Get size
public int getSize() {
return size;
}
//Get length
public int length(){
return length;
}
// Is empty
public boolean isEmpty() {
return size == 0;
}
// Insert element in first position
public void insertFirst(Object element) {
DoubleNode newNode = new DoubleNode(head,element,head.getNext());
head.getNext().setPrior(newNode);
head.setNext(newNode);
size ++;
length = size;
}
// Insert element in last position
public void insertLast(Object element) {
DoubleNode newNode = new DoubleNode(rear.getPrior(),element,rear);
rear.getPrior().setNext(newNode);
rear.setPrior(newNode);
size ++;
length = size;
}
// Remove element from first position
public void removeFirst() throws ExceptionQueueEmpty{
if(isEmpty())
throw new ExceptionQueueEmpty("Queue is empty");
head.getNext().getNext().setPrior(head);
head.setNext(head.getNext().getNext());
size --;
}
// Remove element from last position
public void removeLast() throws ExceptionQueueEmpty{
if(isEmpty())
throw new ExceptionQueueEmpty("Queue is empty");
rear.getPrior().getPrior().setNext(rear);
rear.setPrior(rear.getPrior().getPrior());
size --;
}
// Get first node but not isn't deletion
public Object getFirst() throws ExceptionQueueEmpty{
if(isEmpty())
throw new ExceptionQueueEmpty("Queue is empty");
return head.getNext().getElement();
}
// Get last node but not isn't deletion
public Object getLast() throws ExceptionQueueEmpty{
if(isEmpty())
throw new ExceptionQueueEmpty("Queue is empty");
return rear.getPrior().getElement();
}
//Get all element
public void getAllElements(){
Object[] array = new Object[getSize()];
DoubleNode travelNode = new DoubleNode();
travelNode = head.getNext();
for(int i = 0; travelNode != rear;i ++){
array[i] = travelNode.getElement();
travelNode = travelNode.getNext();
}
System.out.println("All elements are: " + Arrays.toString(array));
}
}
DoubleListQueueTest 类:
package com.doub.list;
import com.queue.ExceptionQueueEmpty;
/** * * @author gannyee * */
public class DoubleListQueueTest {
public static void main(String[] args) throws ExceptionQueueEmpty {
DoubleListQueue dlq = new DoubleListQueue();
System.out.println("Size: " + dlq.getSize());
System.out.println("Is empty? " + dlq.isEmpty());
for(int i = 0;i < 6;i ++){
dlq.insertFirst(i);
}
System.out.println("Size: " + dlq.getSize());
System.out.println("Is empty? " + dlq.isEmpty());
dlq.getAllElements();
System.out.println(dlq.getFirst());
System.out.println(dlq.getLast());
for(int i = 0;i < 6;i ++){
dlq.insertLast(i + 1);
}
System.out.println("Size: " + dlq.getSize());
System.out.println("Is empty? " + dlq.isEmpty());
dlq.getAllElements();
System.out.println(dlq.getFirst());
System.out.println(dlq.getLast());
for(int i = 0;i < 6;i ++){
dlq.removeFirst();
}
System.out.println("Size: " + dlq.getSize());
System.out.println("Is empty? " + dlq.isEmpty());
dlq.getAllElements();
System.out.println(dlq.getFirst());
System.out.println(dlq.getLast());
for(int i = 0;i < 6;i ++){
dlq.removeLast();
}
System.out.println("Size: " + dlq.getSize());
System.out.println("Is empty? " + dlq.isEmpty());
dlq.getAllElements();
}
}
测试结果:
Size: 0
Is empty? true
Size: 6
Is empty? false
All elements are: [5, 4, 3, 2, 1, 0]
5
0
Size: 12
Is empty? false
All elements are: [5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6]
5
6
Size: 6
Is empty? false
All elements are: [1, 2, 3, 4, 5, 6]
1
6
Size: 0
Is empty? true
All elements are: []
参考文献:数据结构与算法( Java 描述)邓俊辉 著