Files
CS-2852/Notes/src/Week1/KWSingleLinkedList.java
2019-08-13 11:40:00 -05:00

237 lines
6.8 KiB
Java

/*
* CS2852
* Spring 2018
* KWLinkedList
* Name: Sean Jones
* Created: 03/07/2018
*/
package Week1;
/**
* This class implements some of the methods of the Java ArrayList class. It
* does not implement the List interface.
* @param <E> Generic type that will be declared by the user
*/
public class KWSingleLinkedList<E> {
private Node<E> head = null;
private int size = 0;
/**
* Returns the element at the specified index (not LinkedList behavior)
*
* Throws an ArrayIndexOutOfBoundsException on invalid index
*
* @param index The index of the element to be returned
* @return The element stored in the specified index
* @throws ArrayIndexOutOfBoundsException thrown when index is invalid
*/
public E get(int index) throws ArrayIndexOutOfBoundsException {
if(index < 0 || index >= size) {
throw new ArrayIndexOutOfBoundsException(index);
}
Node<E> node = getNode(index);
return node.data;
}
/**
* Sets a specified value at a specified index in the list (not LinkedList behavior)
*
* @param index The index where the new value will be stored
* @param newValue The value to be stored in the specified index
* @return The element previously stored at the specified index
* @throws ArrayIndexOutOfBoundsException thrown when index is invalid
*/
public E set(int index, E newValue) throws ArrayIndexOutOfBoundsException {
if(index < 0 || index >= size) {
throw new ArrayIndexOutOfBoundsException(index);
}
Node<E> node = getNode(index);
E result = node.data;
node.data = newValue;
return result;
}
/**
* Special add method for adding the first Node to the KWSIngleLinkedList.
*
* @param item The element to be added as the head of the list
*/
public void addFirst(E item) {
head = new Node<>(item, head);
size++;
}
/**
* Adds a new Node to a specified index of the KWSingleLinkedList (not LinkedList behavior)
* @param index The index where the element will be added
* @param item The element to be added
* @throws ArrayIndexOutOfBoundsException thrown when index is invalid
*/
public void add(int index, E item) throws ArrayIndexOutOfBoundsException {
if(index < 0 || index > size) {
throw new ArrayIndexOutOfBoundsException(index);
}
if(index == 0) {
addFirst(item);
} else {
Node<E> node = getNode(index - 1);
addAfter(node, item);
}
}
/**
* Adds a new Node at the end of the list
*
* @param item The element to be added to the list
* @return true if the element was successfully added, false otherwise
*/
public boolean add(E item) {
add(size, item);
return true;
}
/**
* Removes a Node from the specified index
* @param index The index of the Node to remove
* @return The element removed from the list
* @throws ArrayIndexOutOfBoundsException thrown when index is invalid
*/
public E remove(int index) throws ArrayIndexOutOfBoundsException {
//TODO
return removeAfter(getNode(index-1));
}
/**
* Returns the size (number of elements) in the list
* @return The number of elements in the list
*/
public int size() {
int s = 0;
while (getNode(s) != null) {
s++;
}
return s;
}
/**
* Returns the index of first instance of a specified element
* @param item The specified element
* @return The index of the first instance of the specified, -1 if not found
*/
public int indexOf(E item) {
// TODO
int index = 0;
while (item != get(index) && index < size()-1) {
index++;
}
if (item == get(index)) {
return index;
} else {
return -1;
}
}
/**
* Returns a String representation of the list, showing the next relationships with
* a "==>"
* @return The String representation of the list.
*/
@Override
public String toString() {
Node<E> node = head;
StringBuilder result = new StringBuilder();
while(node != null) {
result.append(node.data);
if(node.next != null) {
result.append(" ==> ");
}
node = node.next;
}
return result.toString();
}
/*
* Helper method that finds and returns the Node at the specified index
*/
private Node<E> getNode(int index) {
if(index < 0 || index > size) {
throw new ArrayIndexOutOfBoundsException(index);
}
Node<E> node = head;
for(int i = 0; i < index && node != null; i++) {
node = node.next;
}
return node;
}
/*
* Helper method that adds an element after the specified Node. A new Node is
* created, the element is assigned to the new Node, and that Node is set as
* the next Node of the specified Node. The size is then incremented to reflect
* the added Node.
*/
private void addAfter(Node<E> node, E item) {
node.next = new Node<>(item, node.next);
size++;
}
/*
* Helper method that removes the Node that follow (is the next of) a specified
* Node. The specified Node's next is set to it's next Node's next. The size is
* then decremented to reflect the removed Node.
*
* The removed Node is then returned.
*/
private E removeAfter(Node<E> node) {
Node<E> temp = node.next;
if (temp != null) {
node.next = temp.next;
size--;
return temp.data;
} else {
return null;
}
}
/*
* Helper method that removes the head of the list. The head's next Node is
* set as the new head of the list. The size is then decremented to reflect
* the removed Node.
*/
private E removeFirst() {
Node<E> temp = head;
if (head != null) {
size--;
return temp.data;
} else {
return null;
}
}
/*
* A private class that wraps data in a Node object to be referenced by the list. Notice that
* all methods, including constructors are private. Since this is a private class and only
* exists inside the containing class, all private fields and methods are accessible by the
* containing class.
*/
private static class Node<E> {
private E data;
private Node<E> next;
private Node(E dataItem) {
this.data = dataItem;
this.next = null;
}
private Node(E dataItem, Node<E> next) {
this.data = dataItem;
this.next = next;
}
}
}