/**
* Implementation of a Singly-Linked List.
*
* @author __your_name___
*/
import java.util.NoSuchElementException;
public class SLinkedList<E>
{
// Representation of the list nodes
private class Node
{
E data; // the data value stored at the node
Node next; // the successor of this node
// creates a node with the given data item and no successor
Node(E d)
{
data = d;
next = null;
}
}
/**
* The first node in the list.
*/
private Node head;
// put comment in Javadoc style
public SLinkedList()
{
head = null;
}
// put comment in Javadoc style
public boolean isEmpty()
{
return head == null;
}
/**
* Adds the given element to the front of the list.
*
* @param data the element to add
*/
public void addFirst(E data)
{
Node node = new Node(data);
node.next = head;
head = node;
}
/**
* Returns the first element in the list.
*
* @return the first element in the list
* @throws NoSuchElementException when the list is empty
*/
public E getFirst()
{
if (this.isEmpty()) {
throw new NoSuchElementException();
}
return head.data;
}
// put comment in Javadoc style
public void addLast(E data)
{
// special case
if (this.isEmpty()) {
head = new Node( data );
}
else {
// find last node
Node curr = head;
while (curr.next != null) {
curr = curr.next;
}
// attach the new node to the last node
Node node = new Node(data);
curr.next = node;
}
}
// put comment in Javadoc style
public boolean remove(E data)
{
Node prevNode = head; // follows one box/node behind currNode
Node currNode = head; // looks for the box/node with item
// as long as currNode is within the list (points to some node)
while (currNode != null) {
if (currNode.data.equals(data)) {
// special case if removing first node
if (head == currNode) {
head = currNode.next;
}
else {
prevNode.next = currNode.next;
}
return true;
}
// advance the pointers, so they are one box/node apart
prevNode = currNode;
currNode = currNode.next;
}
return false;
}
// put comment in Javadoc style
public E removeAt(int index)
{
// how to handle negative indices?
Node prevNode = head; // follows one box/node behind currNode
Node currNode = head; // looks for the box/node with given index
int i = 0; // starting at first box, i.e. 0
// as long as currNode within list and box index not reached, advance
while (currNode != null && i < index) {
prevNode = currNode; // move each
currNode = currNode.next; // one step
i++; // ahead
}
// check whether loop stopped because currNode is null (no boxes left, i.e. index too high)
if ( currNode == null ) {
throw new IndexOutOfBoundsException(); // stops method, done!
}
// if reached here, delete the box
E data = currNode.data; // keep the data
if ( currNode == head ) { // special case for first node
head = head.next; // lose 1st node;
}
else {
prevNode.next = currNode.next; // bypass node
}
return data; // give back the data
}
// put comment in Javadoc style
public String toStringNext()
{
String str = "";
Node curr = head;
// add each data item to the result string
while (curr != null) {
str = str + curr.data + " ";
curr = curr.next;
}
// remove trailing space and enclose in [ ]
str = "[" + str.trim() + "]";
return str;
}
// example of recursive method
public String toString()
{
String str = toString( head ); // call private helper recursive method
// remove trailing space and enclose in [ ]
str = "[" + str.trim() + "]";
return str;
}
// I compute a string from given node to the end
private String toString( Node curr )
{
if ( curr == null ) { // if fell of the list, no items
return "";
}
else {
String strRest = toString( curr.next ); // get string for all to the right
String result = curr.data + " " + strRest; // prepend self to rest
return result;
}
}
}