在学习数据结构与算法分析过程中,便于使用的LinkedList类的实现是个很好的练手项目,本博文将提供详细的代码,给出一个便于使用的LinkedList泛型类的实现。
为了避免与类库中的类相混淆,我们将其命名为MyLinkedList。由于程序较长,也相对简单,不太想逐段分析,我们先将几个注意点指出,后面放出整段程序。
很多关于接口的知识可以参阅 数据结构与算法分析(二) —— ArrayList泛型类的实现
// Build a LinkedList based on P54 of DSAA
public class MyLinkedList<AnyType> implements Iterable<AnyType>
{
//@// Fields
private int theSize;
private int modCount = 0; //the number of modification of the LinkedList
private Node<AnyType> beginMarker; //header node
private Node<AnyType> endMarker; //tail node
//@// Constructors
public MyLinkedList()
{
doClear();
}
//@// Methods
private void clear()
{
doClear();
}
public void doClear()
{
beginMarker = new Node<>( null, null, null );
endMarker = new Node<>( null, beginMarker, null );
beginMarker.next = endMarker;
theSize = 0;
modCount++;
}
public int size()
{
return theSize;
}
public boolean isEmpty()
{
return size() == 0;
}
public boolean add( AnyType x )
{
add( size(),x );
return true;
}
public void add( int idx, AnyType x )
{
addBefore( getNode(idx, 0, size()), x );
}
private void addBefore( Node<AnyType> p, AnyType x )
{
Node<AnyType> newNode = new Node<>(x, p.prev, p);
newNode.prev.next = newNode;
p.prev = newNode;
theSize++;
modCount++;
}
public AnyType get(int idx)
{
return getNode(idx).data;
}
private Node<AnyType> getNode(int idx)
{
return getNode(idx, 0, size()-1);
}
/*
* Gets the Node at position idx, which must range from lower to upper.
* @param idx index to search at.
* @param lower lowest valid index.
* @param upper highest valid index.
* @return internal node corresponding to idx.
* @throws IndexOutOfBoundsException if idx is not between lower and upper, inclusive.
*/
private Node<AnyType> getNode( int idx, int lower, int upper )
{
Node<AnyType> p;
if(idx<lower || idx>upper)
throw new IndexOutOfBoundsException("getNode index: " + idx + "; size: " + size());
if(idx<size()/2)
{
p = beginMarker.next;
for(int i = 0; i<idx; i++)
p = p.next;
}
else
{
p = endMarker;
for(int i = size(); i>idx; i--)
p = p.prev;
}
return p;
}
public AnyType set(int idx, AnyType newVal)
{
Node<AnyType> p = getNode(idx);
AnyType oldVal = p.data;
p.data = newVal;
return oldVal;
}
public AnyType remove(int idx)
{
return remove(getNode(idx));
}
private AnyType remove(Node<AnyType> p)
{
p.next.prev = p.prev;
p.prev.next = p.next;
theSize--;
modCount++;
return p.data;
}
/*
* Returns a String representation of this collection.
*/
public String toString()
{
StringBuilder sb = new StringBuilder("[ ");
for(AnyType x : this)
sb.append(x+" ");
sb.append("}");
return new String(sb);
}
//@// Other classes
// This is the doubly-linked list node
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;
}
}
public java.util.Iterator<AnyType> iterator()
{
return new LinkedListIterator( );
}
/*
* This is the implementation of the LinkedListIterator.
* It maintains a notion of a current position and of
* course the implicit reference to the MyLinkedList.
*/
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);
expectedModCount++;
okToRemove = false;
}
}
}
class testLinkedList
{
public static void main(String[] args)
{
MyLinkedList<Integer> lst = new MyLinkedList<>();
for(int i=0; i<10; i++)
lst.add(i);
for(int i=20; i<30; i++)
lst.add(0,i);
lst.remove(0);
lst.remove(lst.size()-1);
System.out.println(lst);
java.util.Iterator<Integer> itr = lst.iterator();
while(itr.hasNext())
{
itr.next();
itr.remove();
System.out.println(lst);
}
}
}