队列
一说到队列,大家应该很容易想到跟排队有关的事,毕竟咱们泱泱中华一大特色人多哈哈!
计算机中的队列同现实世界的队列几乎相同,举个栗子🌰:午饭前的最后一节课的下课铃一响,人们乌央乌央的都走向食堂(干饭人都是用跑的😄)。
打饭的时候来的最早的人排在最前面,之后依次排开,先到的先打饭,后到的喝稀饭...非常明显的先进先出(FIFO)形式。
在我的博文中目前实现的都是比较简单基础的数据结构,不管是栈、队列还是背包(集合),都比较基础,我觉得首先要把这些基础的写的非常熟练,只要一下手立马能写出来的程度,才能真正搞懂之后复杂一些的数据结构,这一点尤为重要。 说到这里就得说代码量积累了,需要相当程度的有效代码量,才能真正踏入编程的门槛。
骐骥一跃不能十步,驽马十驾功在不舍。
设计思路
同上一篇用链表设计下压栈一样,我们还是使用链表,API方法的设计几乎与下压栈相同。
我们需要队列来存取数据,那么就离不开这两个方法:入列enqueue()、出列dequeue().
其它如size()方法Iterator等基本与下压栈相同。
上代码实现
import org.jetbrains.annotations.NotNull;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* 单链表实现的队列
* @author wangxinfu
*/
public class Queue<Item> implements Iterable<Item>{
/**
* 实际元素数量
*/
private int size;
/**
* 最早添加的结点
*/
private Node first;
/**
* 最近添加的结点,尾节点
*/
private Node last;
/**
* 私有内部类作为栈结构
*/
private class Node{
Item item;
Node next;
}
/**
* 添加遍历iterator的方法
*/
private class QueueIterator implements Iterator<Item>{
/**
* 指向当前结点
*/
private Node current = first;
/**
* 是否为空
* @return
*/
@Override
public boolean hasNext() {
return current!=null;
}
/**
* 从队列的头部,每次调用返回查看一个元素
* @return
*/
@Override
public Item next() {
if(!hasNext()){
throw new NoSuchElementException("Queue is empty!");
}
Item item = current.item;
current = current.next;
return item;
}
}
/**
* 元素添加到队列(从尾部添加)
* @param item
*/
public void enqueue(Item item){
//从尾部添加 last之后
Node oldLast = last;
last = new Node();
last.item = item;
//判断是否是为空队列,空队列则这次为第一个结点,既是
//首结点也是尾节点,否则就是last之后的添加结点
if (isEmpty()){first = last;}
else{oldLast.next = last;}
size++;
}
/**
* 出列
* @return item
*/
public Item dequeue(){
if (isEmpty()){
throw new NoSuchElementException("Queue is empty!");
}
//暂存first
Item item = first.item;
Node next = first.next;
//help GC回收垃圾
first.item = null;
first.next = null;
first = next;
size--;
return item;
}
public int size(){return size;}
public boolean isEmpty(){return first == null;}
@NotNull
@Override
public Iterator<Item> iterator() {
return new QueueIterator();
}
//test
public static void main(String[]args){
Queue<String> queue = new Queue<>();
for (int i=0; i<1000; i++){
queue.enqueue(""+i);
}
System.out.println("Queue size: "+ queue.size());
Iterator<String> iterator = queue.iterator();
System.out.println("=====================================");
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("=====================================");
for (int i = 0;i< 100;i++){
System.out.println(queue.dequeue());
}
System.out.println(queue.size());
}
}
一定要亲手操作,多写几遍,否则,到了以简单数据结构为基础的更复杂结构,直接歇菜了。 下一篇将封装一个集合(背包),该系列基本按照经典数据《算法》第4版的内容排列写下去,部分代码与内容也源自此处。