MyLinkedList类,包含两端的链、表的大小以及一些方法。
Node类,一个节点包含数据以及到前一个节点的链和到下一个节点的链,还有一些适当的构造方法。
LinkedListIterator类,该类抽象了位置的概念,并实现接口Iterator。它提供了方法next、hasNext和remove的实现
使用额外的头节点和尾节点的优点在于,通过排除许多特殊情形极大地简化了编码。例如,如果我不使用头节点,那么删除第1个节点就变成了一种特殊的情况,因为在删除期间我们必须重新调整链表到第1个节点的链。
public class MyLinkedList<AnyType> implements Iterable<AnyType>
{
private static class Node<AnyType>
{
public AnyType data;
public Node<AnyType> prev;
public Node<AnyType> next;
public Node(AnyType d, Node<AnyType> p, Node<AnyType> n)
{
data = d;
prev = p;
next = n;
}
}
private int theSize;
//自从链表构造以来对链表所做的改变次数
//与迭代器里的modCount进行比较
private int modCount = 0;
//头节点
private Node<AnyType> beginMarker;
//尾节点
private Node<AnyType> endMarker;
public boolean add(AnyType x)
{
add(size(), x);
return true;
}
public void add(int index, AnyType x)
{
//根据index获取节点,在该节点前添加x
addBefore(getNode(index, x));
}
public void addBefore(Node<AnyType> p, AnyTyoe x)
{
//在p和p之前插入新节点
Node<AnyType> newNode = new Node<AnyType>(x, p.prev, p);
//更新新节点前一节点的后一节点链接
newNode.prev.next = newNode;
//更新p的前一节点链接
p.prev = newNode;
theSize++;
modCount++;
}
public AnyType get(int index)
{
return getNode(index).data;
}
public AnyType set(int index, AnyType newVal)
{
Node<AnyType> p = getNode(index);
AnyType oldVal = p.data;
p.data = newVal;
return oldVal;
}
public AnyType remove(int index)
{
return remove(getNode(index));
}
private AnyType remove(Node<AnyType> p)
{
p.next.prev = p.prev;
p.prev.next = p.next;
theSize--;
modCount++;
return p.data;
}
private Node<AnyType> getNode(int index)
{
Node<AnyType> p;
if(index < 0 || index > size())
{
throw new IndexOutOfBoundsException();
}
//从头节点或者尾节点开始查找
if(index < size() / 2)
{
p = beginMarker.next;
for(int i = 0; i < index; i++)
{
p = p.next;
}
}
else
{
p = endMarker;
for(int i = size(); i > index; i--)
{
p = p.prev;
}
}
return p;
}
private class LinkedListIterator implements java.util.Iterator<AnyType>
{
private Node<AnyType> current = beginMarker.next;
private int expectedModCount = modCount;
private boolean okToRemove = false;
public boolean hasNext()
{
return current != endMarker;
}
public AnyType next()
{
if(modCount != expectedModCount)
{
throw new java.util.ConcurrentModificationException();
}
if(!hasNext())
{
throw new java.util.NoSuchElementException();
}
AnyType nextItem = current.data;
current = current.next;
okToRemove = true;
return nextItem;
}
public void remove()
{
if(modCount != expectedModCount)
{
throw new java.util.ConcurrentModificationException();
}
if(!okToRemove)
{
throw new IllegalStateException();
}
MyLinkedList.this.remove(current.prev);
okToRemove = false;
expectedModCount++;
}
}
}