队列和栈一样,也是存储受限制的线性表,在队尾插入,在队头输出。所以要使用两个指针分别指向队头和队尾,以此来判断是否队满或者队空。本队列使用链式存储。
先定义节点和函数:节点由data域和next域组成。
class Node {
int data;
Node next;
public Node(int paraValue) {
data = paraValue;
next = null;
}
}
定义首尾节点,创建一个空的线性表,也就是只有队首和队尾。
Node header;//队首
Node tail;//队尾
public LinkedQueue() {
header = new Node(-1);
// header.next = null;
tail = header;
}
下面定义方法,来实现队列的操作:
1.出队操作
在队头删除,就是头节点后面删除。
public int dequeue() {
if (header == tail) {
System.out.println("No element in the queue");
return -1;
} // 队空操作判断
int resultValue = header.next.data;//返回删除节点的值
header.next = header.next.next;//将待删除节点覆盖掉
if (header.next == null) {
tail = header;
} //队空
return resultValue;
}
2.入队操作
关键是怎么实现尾部插入。
public void enqueue(int paraValue) {
Node tempNode = new Node(paraValue);//创建新节点并写入值
tail.next = tempNode;//尾部插入
tail = tempNode;//尾部指针指向新插入的节点
}
3.重写toString方法
可以读取队列中的数据。
public String toString() {
String resultString = "";
if (header.next == null) {
return "empty";
} //队空
Node tempNode = header.next;//定义新节点
while (tempNode != null) {
resultString += tempNode.data + ", ";
tempNode = tempNode.next;
}//输出
return resultString;
}
3.主函数调用
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);
}
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());
}
for (int i = 0; i < 3; i++) {
tempQueue.enqueue(i + 10);
}
System.out.println("Enqueue, the queue is: " + tempQueue.toString());
}
}
结果:
总结:对于队列的判空,直接检测是否header==tail。 使用链表的好处是不会出现队列的假溢出问题,使用顺序表在判空时容易出现“假溢出”,所以用循环队列解决这种问题。