package DataStructures; import java.util.NoSuchElementException; import java.util.Iterator; /** *
A simple implementation of singly linked lists.
* *Lists are created empty, for example: *
* LinkedList list = new LinkedList(); ** after which items can be inserted at the front of the list by *
* list.addFirst(item) ** where item is any Object. * *
Items can be removed from the front of the list by
** list.removeFirst(); ** which removes the first item from the list. * * Lists can be traversed using an iterator, for example: *
* for (Iterator i = list.iterator(); i.hasNext();) {
* System.out.println(e.next());
* {
*
* @see Iterator
*
* @author Peter Williams
*/
public class LinkedList {
private ListNode head; // the front of the list
private int size;
/**
* Constructs an empty list.
*/
public LinkedList() {
head = null;
size = 0;
}
/**
* Tests if the list is empty.
* @return the status of the list.
*/
public boolean isEmpty() {
return (head == null);
}
/**
* Returns the length of the list
* @return the length of the list
*/
public int size() {
return size;
}
/**
* Inserts an item at the front of the list.
* @param item the Object to be inserted.
*/
public void addFirst(Object item) {
head = new ListNode(item, head);
++size;
}
/**
* Returns the first item in the list.
* @return the item at the front of the list.
* @exception NoSuchElementException if the list is empty.
*/
public Object firstItem() {
if (head != null) {
return head.data;
} else {
throw new NoSuchElementException();
}
}
/**
* Removes the first item from the list.
* @exception NoSuchElementException if the list is empty.
*/
public void removeFirst() {
if (head != null) {
head = head.next;
--size;
} else {
throw new NoSuchElementException();
}
}
/**
* Tests whether an item is present in the list.
* @param item the object to be searched for.
* @return true if the item is present,
* false otherwise
*/
public boolean contains(Object item) {
ListNode current = head;
while (current != null) {
if (item.equals(current.data)) {
return true;
} else {
current = current.next;
}
}
return false;
}
/**
* Reverses the list.
*/
public void reverse() {
ListNode current = head;
head = null;
while (current != null) {
ListNode save = current;
current = current.next;
save.next = head;
head = save;
}
}
/**
* Iterates over the items in the list.
* @return the iterator.
* @exception NoSuchElementException if the next method
* is called when there is no next element
* @exception IllegalStateException if the next method has not
* yet been called, or the remove method has already
* been called after the last call to the next
* method.
*/
public Iterator iterator() {
return new Iterator() {
private ListNode header = new ListNode(null, head);
private ListNode previous = header;
private ListNode current = head;
private boolean removeOk = false;
public boolean hasNext() {
return current != null;
}
public Object next() {
if (current != null) {
Object result = current.data;
current = current.next;
if (removeOk) {
previous = previous.next;
}
removeOk = true;
return result;
} else {
throw new NoSuchElementException();
}
}
public void remove() {
if (removeOk) {
previous.next = current;
head = header.next;
--size;
removeOk = false;
} else {
throw new IllegalStateException();
}
}
};
}
/**
* Implements the equals method.
* @param other the second linked list.
* @return true if the lists are equal, false otherwise.
*/
public boolean equals(Object other) {
if (other == null ||
!(other instanceof LinkedList) ||
this.size != ((LinkedList) other).size) {
return false;
}
ListNode p = this.head;
ListNode q = ((LinkedList) other).head;
while (p != null) {
if (!p.data.equals(q.data)) {
return false;
}
p = p.next;
q = q.next;
}
return true;
}
/**
* Converts the list to a string.
* @return the string representation.
*/
public String toString() {
String string = "";
string += "[";
if (head != null) {
string += head.data;
ListNode current = head.next;
while (current != null) {
string += ", " + current.data;
current = current.next;
}
}
string += "]";
return string;
}
}