Reversing a Linked List not working as expected - java

I am currently trying to reverse a linked list, I have an unexpected problem where it doesn't print correctly. And when I try and access the values of the linked list I get an error. I would greatly appreciate an expert eye to see what I am missing. Thanks in advance.
public class SinglyLinkedList<E> implements Cloneable, Iterable<E>, List<E> {
//---------------- nested Node class ----------------
/**
* Node of a singly linked list, which stores a reference to its
* element and to the subsequent node in the list (or null if this
* is the last node).
*/
private static class Node<E> {
private E data; // reference to the element stored at this node
private Node<E> nextNode;
//methods for accessing variables
public Node<E> getNextNode() { return nextNode; }
public E getData() { return data; }
// Modifier methods
public void setNext(Node<E> n) { nextNode = n; }
public void setData(E n) { data = n; }
public Node(E e, Node<E> n) {
nextNode = n;
data = e;
}
// reference to the subsequent node in the list// TODO
} //----------- end of nested Node class -----------
// instance variables of the SinglyLinkedList
private int size = 0; // number of nodes in the list
private Node<E> head = null; // head node of the list (or null if empty)
public SinglyLinkedList() {
} // constructs an initially empty list
// access methods
/**
* Returns the number of elements in the linked list.
*
* #return number of elements in the linked list
*/
public void addFirst(E e) {
head = new Node<E>(e, head); // create the new node and link new node
size++;
}
/**
* Produces a string representation of the contents of the list.
* This exists for debugging purposes only.
*/
public String toString() {
StringBuilder temporaryString = new StringBuilder();
temporaryString.append("[");
for(Iterator<E> iterator = iterator(); iterator.hasNext();){
temporaryString.append(iterator.next()).append(", ");
}
temporaryString.deleteCharAt(temporaryString.length() - 1);
temporaryString.deleteCharAt(temporaryString.length() - 1);
temporaryString.append("]");
return temporaryString.toString();
}
private class SinglyLinkedListIterator implements Iterator<E> {
private Node<E> current;
public SinglyLinkedListIterator() {
current = head;
}
#Override
public boolean hasNext() {
return current != null;
}
#Override
public E next() {
if(!hasNext()) throw new RuntimeException("No such element");
E res = current.getData();
current = current.getNextNode();
return res;
}
}
public Iterator<E> iterator() {
return new SinglyLinkedListIterator();
}
The reverse Linked List method:
public Node<E> reverseLinkedList(SinglyLinkedList sll) {
Node<E> previous = null;
Node<E> current = sll.head;
while (current != null) {
Node<E> nextElement = current.getNextNode();
current.setNext(previous);
previous = current;
current = nextElement;
}
return previous;
}
The main method:
public static void main(String[] args) {
SinglyLinkedList<Integer> sll2 = new SinglyLinkedList<Integer>();
sll2.addFirst(1);
sll2.addFirst(2);
sll2.addFirst(3);
System.out.println(sll2.toString());
sll2.reverseLinkedList(sll2);
System.out.println(sll2.toString());
}
The output:
[3, 2, 1]
//i should expect to get 1,2,3
[3]

As you are mutating ("rewiring") the given linked list in the reverseLinkedList function, you are not actually producing a new linked list. So to have it return something is actually contradictory. Either it should return a completely new linked list without mutating the given one, or it should mutate the given linked list and not return anything.
From your main code I see that you actually expect to mutate the given linked list, as you don't use the returned value and print the result based on sll. So make your function a void one, and drop the return statement.
The core problem now is that you never change the head member: it still references what used to be the first node in the list, but is now the last one. You should assign the node to head that previously was the tail node.
So the last statement in your function should be:
sll.head = previous;

Related

Implementing a method in the linkedList that returns the current node

I'm implementing a generic linkedList, but I had a hard time writing a function that returns the current node. It always returns the last added node. I'm sharing my code below.
I have searched for similar questions but I didn't find what I want.
Here's the linkedList file. I'm sure the add method which is vorne() is working as expected. It adds elements at the beginning.
public class Liste<T> {
// Points to the head of the Linked List
// i.e the first element
Node<T> head;
Node<T> tail;
static int size = 0;
static class Node<T> {
// Data Stored in each Node of the Linked List
T data;
// Pointer to the next node in the Linked List
Node<T> next;
// Node class constructor used to initializes the data
// in each Node
private Node(T data) {
this.data = data;
next = null;
}
}
public static <T> Liste<T> neu() {
Liste<T> l = new Liste<T>();
return l;
}
public static <T> Liste<T> einfuegen(Liste o, T auD, Nat nat) {
return null;
}
// Add element at the beginning
public static <T> Liste<T> vorne(Liste<T> list, T data) {
//Create new node
Node newNode = new Node(data);
//Checks if the list is empty.
if(list.head == null) {
//If list is empty, both head and tail would point to new node.
list.head = newNode;
list.tail = newNode;
newNode.next = list.head;
size++;
}
else {
//Store data into temporary node
Node temp = list.head;
//New node will point to temp as next node
newNode.next = temp;
//New node will be the head node
list.head = newNode;
//Since, it is circular linked list tail will point to head.
list.tail.next = list.head;
size++;
}
return list;
}
// This method should return the last added element
public static <T> T kopf(Liste<T> lNat) {
// Throws an Exception if the List is empty
if (lNat.head == null) {
System.out.print("No Element found");
}
return lNat.head.data;
}
// This method should return all the elements except the first element.
public static <T> Liste<T> rest(Liste<T> lString) {
// TODO Auto-generated method stub
if (lString.head != null) {
lString.head = lString.head.next;
}
return lString;
}
public int getCount() {
return size;
}
}
The problem arises here!
public static void main(String[] args) {
// TODO Auto-generated method stub
Liste<String> l0 = Liste.neu();
Liste<String> l1a = Liste.vorne(l0, "AuD");
Liste<String> l1b = Liste.vorne(l0, "PFP");
Liste<String> l2a = Liste.vorne(l1a, "FAUL");
Liste<String> l2b = Liste.vorne(l1b, "FAIL");
//Liste<String> l1x = Liste.rest(l2b);
//Liste<String> l1y = Liste.rest(l2b);
//Liste<String> l0x = Liste.rest(l1x);
//Liste<String> l0y = Liste.rest(l1y);
//String l0y = Liste.kopf(l2a);
System.out.println(l1b.getCount());
System.out.println(Liste.kopf(l2a));
}
The output:
4
FAIL
when I call the kopf method which supposes to return the last added element, it returns the string "FAIL" instead of "FAUL". I have stored it in a separate object, and I am calling l2a object, so why it's returning "FAIL". As you can see, I'm creating a new list using neu() method, then I'm using the same list to add elements. I think it's a silly bug that I don't see.
It seems I can't figure it out. Please any help would be appreciated.

Java Priority Queue in Linked List Test Cases

So I'm trying to implement a priority queue with a linked list. I think I have the basics together, but for some reason my test cases aren't working. When I run it, the size show up fine, but none of the node values are showing (only an arrow "->" pops up once). If anyone could help me figure out why it isn't working, or suggest a better way to set up test cases in java (I've never done that before) it would be appreciated!
Node class:
public class Node { //Node class structure
int data; //data contained in Node; for assignment purposes, data is an int
Node next; //pointer to Next Node
//Node Constructor
public Node(int data) {
this.data = data;
next = null;
}
//Set Methods
public void setData(int data) { //set Node value
this.data = data;
}
public void setNext(Node next) { //set next Node value
this.next = next;
}
//Get Methods
public int getData() { //get Node value
return this.data;
}
public Node getNext() { //get next Node value
return this.next;
}
//Display the Node Value
public void displayNode() {
System.out.println(data + "urgh"); //display value as a string
}
}
Linked List Class:
import Question1.Node;
//basic set-up of a FIFO singly linked list
public class SLList{
protected Node head; //head of SLList
protected Node tail; //tail of SLList
int n; //number of elements in SLList
//SLList constructor
public SLList() {
head = null;
n = 0;
}
//check if list is empty
public boolean isEmpty() {
return head == null;
}
//return the size of the list
public int size() {
return n;
}
//add a new node to the end of the list
public boolean insert(int x){
Node y = new Node(x);
if (head == null){ //if head is null, thus an empty list
head = y; //assign head as y
}
else{ //if there is already a tail node
tail.next = y; //assign the tail's pointer to the new node
}
tail = y; //assign tail to y
this.n++; //increment the queue's size
return true; //show action has taken place
}
//remove and return node from head of list
public Node remove(){
if (n == 0){ //if the list is of size 0, and thus empty
return null; //do nothing
}
else{ //if there are node(s) in the list
Node pointer = head; //assign pointer to the head
head = head.next; //reassign head as next node,
n--; //decrement list size
return pointer; //return the pointer
}
}
//display SLList as string
public void displayList() {
Node pointer = head;
while (pointer != null) {
pointer.displayNode();
pointer = pointer.next;
}
System.out.println(" ");
}
}
Priority Queue Class:
import Question1.Node;
import Question1.SLList;
public class PriorityQueue extends SLList {
private SLList list; //SLList variable
public PriorityQueue(){ //create the official SLList
list = new SLList();
}
//add a new node; new add method that ensures the first element is sorted to be the "priority"
public boolean add(int x){
Node y = new Node(x);
if (n == 0){ //if there are 0 elements, thus an empty list
head = y; //assign head as y
}
else if (y.data < head.data){ //if new node y is the smallest element, thus highest priority
y.next = head; //assign y's next to be current head of queue
head = y; //reassign head to be actual new head of queue (y)
}
else{ //if there is already a tail node
tail.next = y; //assign the tail's pointer to the new node
}
tail = y; //assign tail to y
n++; //increment the queue's size
return true; //show action has taken place
}
//delete the minimim value (highest priority value) from the queue and return its value
public Node deleteMin(){
return list.remove(); //the list is sorted such that the element being removed in indeed the min
}
//return the size of the queue
public int size() {
return n;
}
//display Queue as string
public void displayQueue() {
System.out.println("->");
list.displayList();
}
}
Test Cases (so far, the delete one wasn't working so it's commented out):
import Question1.PriorityQueue;
public class TestQ1 { //Test code
public static void main(String[] args){
PriorityQueue PQueue1 = new PriorityQueue();
PQueue1.add(3);
PQueue1.add(2);
PQueue1.add(8);
PQueue1.add(4);
System.out.println("Test add(x): ");
PQueue1.displayQueue();
System.out.println("Test size(): " + PQueue1.size());
PriorityQueue PQueue2 = new PriorityQueue();
//Node node1 = PQueue1.deleteMin();
System.out.println("Test deleteMin():");
PQueue2.displayQueue();
System.out.println("Test size(): " + PQueue2.size());
}
}
Change list.displayList() to displayList(), and you'll see the expected output.
Why? Because your queue is already a list (that is, an instance of SLList). When a class A extends another class B, an instance of A is also an instance of B. This is inheritance.
You've also included an instance variable private SLList list within your PriorityQueue implementation, which is an example of composition. Generally you'll only do one or the other of these two options, depending on your situation. In this case it seems you're trying to use inheritance, so there's no reason to create a separate list instance variable. You're adding the data directly to the queue (using the fact that, intrinsically, it is a list in its own right).
You should remove the list instance variable, and all the usages of it should refer to the parent class' methods or variables.

Singly Linked List implementation in Java Iterator

I'm writing a simple implementation of a Bag in Java. I am implementing Iterable and writing my own LinkedList Iterator. So I'm racking my brain; I am trying to add elements to the linked list. I have a working implementation (the commented out code in the add() function). However, I do not understand why the following code does not work:
current.item = item;
Node<T> nextNode = new Node<T>();
current.next = nextNode;
current = nextNode;
So, given that the list is empty and the current head is initialized but has no item or next: I assign item to the current item, create a new node, set it to the current's next and change the current (head) to the node I just created. Adding two items to the list, I printed out the objects for posterity:
current: Bag$Node#4524411f next: Bag$Node#401e7803
current: Bag$Node#401e7803 next: Bag$Node#10dba097
current: Bag$Node#10dba097 next: Bag$Node#1786f9d5
current: Bag$Node#1786f9d5 next: Bag$Node#704d6e83
It looks clearly, to me at least, that the next is getting set with a new node each time just fine. I get all four elements added to the bag, but the item is lost and returns null for each index. The toArray() function shows [null, null, null, null]
I'm sure it's something blindingly simple. Below is the entire implementation.
import java.util.Iterator;
public class Bag<T> implements Iterable<T> {
private Node current;
//Node<T> head;
private int numberofProducts;
T[] myBag;
int defaultCapacity;
public Iterator<T> iterator() {
return new ListIterator<T>(current);
}
public Bag(int defaultCapacity) {
this.current = new Node<T>();
this.numberofProducts = 0;
this.defaultCapacity = defaultCapacity;
}
public void add(T item) {
if(isFull()) {
System.out.println("bags full, yo");
return;
}
current.item = item;
Node<T> nextNode = new Node<T>();
current.next = nextNode;
current = nextNode;
numberofProducts++;
//Node<T> nextNode = current;
//current = new Node<T>();
//current.item = item;
//current.next = nextNode;
//numberofProducts++;
}
public Object[] toArray() {
Object[] array = new Object[size()];
int i = 0;
Node<T> node = current;
//Node<T> node = head;
while(node.next != null) {
array[i] = node.item;
node = node.next;
i++;
}
return array;
}
public boolean isEmpty() {
return this.numberofProducts <= 0;
}
public boolean isFull() {
return this.numberofProducts >= defaultCapacity;
}
public int size() {
return this.numberofProducts;
}
private class Node<T> {
private T item;
private Node<T> next;
}
private class ListIterator<T> implements Iterator<T> {
private Node<T> current;
public ListIterator(Node<T> first) {
current = first;
}
public boolean hasNext() {
return current != null;
}
public T next() {
if(hasNext()) {
T item = current.item;
current = current.next;
return item;
}
return null;
}
public void remove() {
}
}
}
The item values aren't lost. The problem is that you lose track of the head of the linked list. Your current variable keeps track of the tail already, and since your toArray() method starts at current, the while loop never executes because there are no elements after the tail element of the list.
Consequently, you just end up with an array of default-initialized Object values, i.e. null.
To fix this, you need another instance variable to keep track of the head of the list, and this is what you'll use in your toArray() method.
From what I can see, the reason it's not acting as a Linked List is because you are not retaining a reference to the first element added. Rather you retain a reference to the last (current) element added.
You can resolve this by adding a class field reference the first element added
T head
Then in your add() method, set head to the Node you create. Then when you construct your ListIterator, pass head as the parameter.
You can change add(T item) to showing like this:
public void add(T item) {
if (!isFull()) {
Node<T> toAdd = new Node<>();
toAdd.item = item;
current.next = toAdd;
current = toAdd;
if (head == null) {
head = toAdd;
}
}
}
Then add the class field Node<T> head to your Bag<T> class.
Additionally, I'm not sure why Node is a static class, plus a number of other changes I won't get into now, but I guess the class is incomplete at present.
The problem is with your logic written in the add() method. Whenever adding the new data to Bag, your root node is changing and pointing to the last node of your Bag. Since the next to last node is null, that's why the iterator is not returning anything. Refer to this link for the exact solution.

Exception in thread "main" java.lang.NullPointerException error - Eclipse Java linked lists

I'm creating a Stack Data Structure and am implementing it using a Linked List. I am using 3 java files - stack.java, stacktest.java and linkedList.java. The linked list works fine when I test it but the stack test is giving me the following errors
Is Empty?: true
Is Empty?: false
Exception in thread "main" java.lang.NullPointerException
at Stack.Peek(Stack.java:56)
at StackTest.main(StackTest.java:12)
Here is my stack.java file
import java.util.EmptyStackException;
public class Stack{
linkedList list;
int count;
public Stack()
{
list = new linkedList();
count = 0;
}
/**
* Adds a node to the head of the list
* #param c character to add
*/
public void Push(char c)
{
if(list.isEmpty())
{// If the list is empty
list.addFirst(c); // Add first
count++;
}
else
{
list.addAtEnd(c); // To the end (tail acts as head)
count++;
}
}
/**
* Removes a node from the head of the list
* #return char removed node
*/
public char Pop() throws EmptyStackException
{
if (!isEmpty())
{
return list.removeLast();
}
else
{
throw new EmptyStackException();
}
}
/**
* Returns the char from the head of the list
* #return char from top of the list
*/
public char Peek() throws EmptyStackException
{
if (!isEmpty())
{
return list.getTail().ch;
}
else
{
throw new EmptyStackException();
}
}
/**
* Is the list empty?
* #return true=yes false=no
*/
public boolean isEmpty()
{
return list.isEmpty();
}
/**
* Counts number of nodes within the list
* #return int # nodes in list
*/
public int getCount()
{
int counter = 0;
Node temp = list.getHead(); // Get head pointer.
while(temp.next != null) // Iterate until tail is reached.
counter++; // Increment counter on each node
return counter;
}
public void printStack()
{
list.printList();
}
}
My stacktest.java
import java.io.IOException;
public class StackTest {
public static void main(String args[]) throws IOException
{
Stack stackList = new Stack();
System.out.println("Is Empty?: " + stackList.isEmpty());
stackList.Push('A');
System.out.println("Is Empty?: " + stackList.isEmpty());
stackList.Pop();
stackList.Peek();
stackList.isEmpty();
stackList.getCount();
stackList.printStack();
}
}
And my linkedList.java
class Node
{
protected char ch;
protected Node next;
protected Node previous;
/**
* Construct a node with the given character value
* #param c - The character
*/
public Node (char c)
{
this.ch = c;
this.next = null;
this.previous = null;
}
}
public class linkedList
{ /** A reference to the head of the list */
protected Node head;
protected Node tail;
/**
* Construct a new empty list
*/
public linkedList()
{
head=null;
tail=null;
}
public Node getHead()
{
return head;
}
public Node getTail()
{
return tail;
}
/**
*Set c as first node in the list
*#param c The character to be inserted
*/
public void addFirst(char c)
{
Node newNode = new Node(c);
head=newNode; // Adding new element.
tail=newNode; // Head and tail will be the same.
}
/**
*Add a character to the end of the list
*#param c The character to be inserted
*/
public void addAtEnd(char c)
{
Node nod = new Node(c);
Node temp = head;
while (temp.next != null) // cycle until at end of list.
temp = temp.next;
temp.next=nod; // last element is new node.
nod.previous=temp; // linking last node with rest of list.
tail=nod; // new node is the tail.
}
/**
*Add a character in alphabetical order into the list
*#param c The character to be inserted
*/
public void addInOrder(char c)
{
Node n= new Node(c);
if(isEmpty())
{
addFirst(c);
}
else
{
Node pre=head;
Node succ= head.next;
if (n.ch < pre.ch)
{
n.next =head;// join node n to the list at the head.
head = n;// head is reading from n.
}
else
{
while(succ!=null && n.ch > succ.ch)
{ // find the position to insert the node
pre = succ;
succ = pre.next;
} //rearrange pointers
n.next = succ;
pre.next = n;
}
}
}
/**
*Test to see if this list is empty
*#returns true or false
*/
public boolean isEmpty()
{
return (head == null && tail == null);
}
/**
*removes a node from the head of the list
*#returns c The character from the removed node
*/
public char removeFirst()
{
if(!isEmpty())
{
// a temporary pointer to enable return of the char being removed
Node temp = head;
head = head.next; // move head pointer along the list
return temp.ch;
}
else
{
System.out.println("List is empty");
return '?'; //to indicate that the list is empty
}
}
/**
* removes a node from the tail of the list
* #return c The character from the removed node
*/
public char removeLast()
{
Node t = getTail(); // Retrieve tail
tail = t.previous; // Set tail to previous node
return t.ch; // return character
}
/**
*prints the characters in the list
*/
public void printList()
{
Node temp=head;
while(temp!=tail.next)
{
System.out.print(temp.ch + " ");
temp=temp.next;
}
System.out.println(); // After print, goes to new line.
}
}
I understand that I am using a variable which is null but can someone explain to me where I am going wrong
When you call addFirst(), it sets both the head and the tail to the new node. However, when you removeLast(), it only changes tail to null and leaves head set to the node you popped.
Then, when you call isEmpty(), since head is not null, it doesn't recognize that the list is empty and returns false.
You need to modify removeLast() to check whether you're removing the only element in the list, and update the head accordingly.
Once you have popped out your only element of the stack, the inner list is empty. Therefore list.getTail() will return null, and you cannot peek into your stack anymore.
In StackTest.java you are inserting one element into the stack, then popping it and then trying to peek into the stack. Your pop function is using removeLast method of linkedList.java. While you are correctly pointing the tail to tail.previous, you need to also check if the result of this leads to tail becoming null (which means you have removed the last element in your linked list). You should check for this in removeLast and make head = tail if this is the case:
public char removeLast()
{
Node t = getTail(); // Retrieve tail
tail = t.previous; // Set tail to previous node
if(tail == null){
head = tail;
}
return t.ch; // return character
}
This way isEmpty() method will always return true if you have popped out the last element in the list. You will have to make a similar change to removeFirst() as follows:
public char removeFirst()
{
if(!isEmpty())
{
// a temporary pointer to enable return of the char being removed
Node temp = head;
head = head.next; // move head pointer along the list
if(head == null){
tail = head;
}
return temp.ch;
}
else
{
System.out.println("List is empty");
return '?'; //to indicate that the list is empty
}
}
After this change your peek() method will now throw an EmptyStackException (which is desirable) instead of a NPE when you try to peek into an empty stack.
Might I also suggest that you don't need to traverse the whole list to add at the end of the list (on addAtEnd()). Since you already have the tail you can just append to the end of the tail pointer.

SLinkedList and Node in Java

To start with, yes, this is for an assignment in class, but my lack of understanding on how it operates is higher than I want it to be.
We were given 3 classes, they are the following:
SLinkedList.java
package chapter3.linkedList;
public class SLinkedList<V> {
// instance variables. Add the tail reference.
protected Node<V> head, tail;
protected long size;
// methods, empty list constructor first
public SLinkedList () {
head = null;
tail = null;
size = 0;
} // end constructor of a SLinkedList
// method to add nodes to the list. Storage space for the node
// is already allocated in the calling method
public void addFirst (Node<V> node) {
// set the tail only if this is the very first node
if (tail == null)
tail = node;
node.setNext (head); // make next of the new node refer to the head
head = node; // give head a new value
// change our size
size++;
} // end method addFirst
// addAfter - add new node after current node, checking to see if we are at the tail
public void addAfter (Node<V>currentNode, Node<V>newNode) {
if (currentNode == tail)
tail = newNode;
newNode.setNext (currentNode.getNext ());
currentNode.setNext (newNode);
// change our size
size++;
} // end method addAfter
// addLast - add new node after the tail node. Adapted from Code Fragment 3.15, p. 118.
// Mike Qualls
public void addLast (Node<V> node) {
node.setNext (null);
tail.setNext (node);
tail = node;
size++;
} // end method addLast
// methods to remove nodes from the list. (Unfortunately, with a single linked list
// there is no way to remove last. Need a previous reference to do that. (See
// Double Linked Lists and the code below.)
public Node<V> removeFirst () {
if (head == null)
System.err.println("Error: Attempt to remove from an empty list");
// save the one to return
Node<V> temp = head;
// do reference manipulation
head = head.getNext ();
temp.setNext(null);
size--;
return temp;
} // end method removeFirst
// remove the node at the end of the list. tail refers to this node, but
// since the list is single linked, there is no way to refer to the node
// before the tail node. Need to traverse the list.
public Node<V> removeLast () {
// // declare local variables/objects
Node<V> nodeBefore;
Node<V> nodeToRemove;
// make sure we have something to remove
if (size == 0)
System.err.println("Error: Attempt to remove fron an empty list");
// traverse through the list, getting a reference to the node before
// the trailer. Since there is no previous reference.
nodeBefore = getFirst ();
// potential error ?? See an analysis and drawing that indicates the number of iterations
// 9/21/10. size - 2 to account for the head and tail nodes. We want to refer to the one before the
// tail.
for (int count = 0; count < size - 2; count++)
nodeBefore = nodeBefore.getNext ();
// save the last node
nodeToRemove = tail;
// now, do the pointer manipulation
nodeBefore.setNext (null);
tail = nodeBefore;
size--;
return nodeToRemove;
} // end method removeLast
// method remove. Remove a known node from the list. No need to search or return a value. This method
// makes use of a 'before' reference in order to allow list manipulation.
public void remove (Node<V> nodeToRemove) {
// declare local variables/references
Node<V> nodeBefore, currentNode;
// make sure we have something to remove
if (size == 0)
System.err.println("Error: Attempt to remove fron an empty list");
// starting at the beginning check for removal
currentNode = getFirst ();
if (currentNode == nodeToRemove)
removeFirst ();
currentNode = getLast ();
if (currentNode == nodeToRemove)
removeLast ();
// we've already check two nodes, check the rest
if (size - 2 > 0) {
nodeBefore = getFirst ();
currentNode = getFirst ().getNext ();
for (int count = 0; count < size - 2; count++) {
if (currentNode == nodeToRemove) {
// remove current node
nodeBefore.setNext (currentNode.getNext ());
size--;
break;
} // end if node found
// change references
nodeBefore = currentNode;
currentNode = currentNode.getNext ();
} // end loop to process elements
} // end if size - 2 > 0
} // end method remove
// the gets to return the head and/or tail nodes and size of the list
public Node<V> getFirst () { return head; }
public Node<V> getLast () { return tail; }
public long getSize () { return size; }
} // end class SLinkedList
Node.java
package chapter3.linkedList;
public class Node<V> {
// instance variables
private V element;
private Node<V> next;
// methods, constructor first
public Node () {
this (null, null); // call the constructor with two args
} // end no argument constructor
public Node (V element, Node<V> next) {
this.element = element;
this.next = next;
} // end constructor with arguments
// set/get methods
public V getElement () { return element; }
public Node<V> getNext () { return next; }
public void setElement (V element) { this.element = element; }
public void setNext (Node<V> next) { this.next = next; }
} // end class Node
and GameEntry.java
package Project_1;
public class GameEntry
{
protected String name; // name of the person earning this score
protected int score; // the score value
/** Constructor to create a game entry */
public GameEntry(String name, int score)
{
this.name = name;
this.score = score;
}
/** Retrieves the name field */
public String getName()
{
return name;
}
/** Retrieves the score field */
public int getScore()
{
return score;
}
/** Returns a string representation of this entry */
public String toString()
{
return "(" + name + ", " + score + ")";
}
}
I've spent the past 3 hours listening to his lecture, reading through the text (Data Structures and Algorithms 5th Edition), and looking through internet forums and youtube videos, but I can't seem to grasp any understanding of how to utilize the node/slinkedlist class.
The object of the assignment is "Write a class that maintains the top 10 scores or a game application, implementing the add and remove methods, but using a single linked list instead of an array.
I don't want someone to do this for me, but I do want to know how to make the linked list. I know these are NOT that hard, but doing them with this code he's given has become painfully difficult, any help would be really appreciated.
Thank you in advance.
Edit:
My main function: ScoresTest.java
package Project_1;
public class ScoresTest {
/**
* #param args
*/
public static void main(String[] args)
{
GameEntry entry;
Scores highScores = new Scores();
entry = new GameEntry("Anna", 600);
highScores.add(entry);
entry = new GameEntry("Paul", 720);
highScores.add(entry);
System.out.println("The Original High Scores");
System.out.println(highScores);
entry = new GameEntry("Jill", 1150);
highScores.add(entry);
System.out.println("Scores after adding Jill");
System.out.println(highScores);
}
}
This is for the most part exactly how it should end up looking, but it's everything that makes this work that's throwing me off...well...everything dealing with the 3 classes mentioned above, I could do this if they weren't a factor without too much of an issue, they are what's causing my blank.
Here is a skeleton, without doing much for you this at least talks you through what you have so far in the comments above:
public class ScoreDriver
{
public static void main(String[] args)
{
SLinkedList<GameEntry> sll = new SlinkedList<GameEntry>();
}
}
Once you have this in eclipse, auto-complete will take you pretty far. Instantiating the linked list class with generics could be odd if you've never seen them before. Focus, on SLinkedList though it has a lot of utility for what you want to do, don't worry about Node too much upfront.

Categories

Resources