话不多说,直接进入正题吧,代码很详细:
/*
1.链表是一种递归的数据结构,它或者为空(null),或者是指向一个节点(node)的引用,该节点含有一个泛型的元素和一个指向另一条链表的引用;
2.嵌套类来定义抽象数据类型:
private class Node
{
Item item;
Node next;
}
3.Node的初始化为null;
4.
*/
import java.util.Iterator;
public class QueueNode<Item> implements Iterable<Item>//声明可迭代的接口类型
{
private Node first;//队首
private Node last; //队尾
private int N; //元素数量
private class Node//定义节点
{//定义节点的嵌套类
Item item;
Node next;
}
public boolean isEmpty() {return first==null;}//或:N==0 判断队列是否为空
public int size() {return N;}//队列长度
public void enqueue(Item item)//向队尾添加元素
{
Node oldlast=last;//好像叫起别名
last=new Node();//这步容易漏掉
last.item=item;
last.next=null;
if(isEmpty()) first=last;
else oldlast.next=last;
N++;
}
public Item dequeue()//删除队首的元素
{
Item item=first.item;
first=first.next;//first无法再访问原来的节点了,曾经的节点对象变成了一个孤儿,Java内存管理系统最终将回收它所占的内存
if(isEmpty()) last=null;
N--;
return item;
}
public Iterator<Item> iterator() {return new ListIterator();}//这段代码保证了类必然会实现方法hasNext(),next()和remove()供用例foreach()使用
private class ListIterator implements Iterator<Item>
{
private Node current=first;
public boolean hasNext() {return current!=null;}
public void remove() {};//希望避免在迭代中穿插能够修改数据结构的操作;如果用例调用了remove()则抛出UnsupportedOperationException
public Item next()
{
Item item=current.item;
current=current.next;
return item;
}
}
}
//可以通过迭代语句对Node进行迭代,代码如下:
Stack<String> collection=new Stack<String>();
Iterator<String> i=collection.iterator();
while(i.hasNext())
{
String s=i.next();
StdOut.println(s);
}
// 或者:
Stack<String> collection=new Stack<String>();
for(String s:collection)
StdOut.println(s);
//如果要进行链尾的删除,在缺少其他信息的情况下,唯一的解决办法就是遍历整个链表,找到倒数第二个结点,但是z这个方案所需的时间和链表的长度成正比;
//最好的解决办法是使用双链表。
//链表的遍历:
for(Node x=first;x!=null;x=x.next)
{
//执行操作
}
参考:《算法第四版》 Robert Sedgewick、Kevin Wayne (谢路云译) P96