This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
this is for an assignment. I need to implement a queue using linked lists. I keep getting a null pointer exception while using my enqueue method for my listQueue Class. I'm not too sure what is going on. Below are my main class and listQueue Class.
public class Driver{
public static void main(String[] args) {
MyQueue<Integer> q = null;
boolean useList = true; // make it false if you want to array implementation
if (useList)
q = new ListQueue<Integer>(); // default setting: use a list to implement the queue. You can change it.
else
q = new ArrayQueue<Integer>();
for(int i = 0; i < 1000; i++) // add a large number of items onto the queue
{
q.enqueue(i);
}
System.out.println("Now, dequeue items!");
while(!q.isEmpty())
{
System.out.print(q.dequeue() + " ");
}
System.out.println("\nEnd of dequeueing");
// you should fully test/debug all methods!
}
}
public class ListQueue<T> implements MyQueue<T> {
private class Node {
T item; // public
Node next; // null
}
private Node head = null;
private Node tail = null;
private int size = 0; //size of the list
public ListQueue(){}
/**
* is empty?
*/
public boolean isEmpty() {
// your implementation here:
if (size == 0) {
return true;
}//end if
return false;
}//end isEmpty
/**
* #return the number of items in the queue
*/
public int size() {
// your implementation here:
return size;
}//end size
/**
* enqueue: add an element at the tail of queue
*/
public void enqueue(T item) {
// your implementation here:
if (size == 0) {
head = new Node();
head.item = item;
head.next=tail;
size++;
}//end if
else{
Node newNode = new Node();
newNode.item=item;
tail.next = newNode;
tail = newNode;
size++;
}//end else
}
/**
* dequeue: remove and return the head of the queue
*
* #return the deleted value
* #throws NoSuchElementException if queue is empty
*/
public T dequeue() {
// your implementation here:
if(isEmpty()){
throw new NoSuchElementException();
}//end if
else{
Node temp = head;
head = head.next;
size--;
return temp.item;
}//end else
}//end dequeue
/**
* peek: view the head of queue without removing it.
*
* #return Null if queue is empty
*/
public T peek() {
// your implementation here:
if(isEmpty()){
return null;
}//end if
else{
return head.item;
}//end else
}//end peek
}//end ListQueue
After adding one element to the list, your tail pointer is null. When you add another element to the list, you try to dereference the null pointer which causes the error:
tail.next = newNode;
You need to make sure that for non-empty queues, the head and tail pointers are always pointing to a node. When the queue is size 1, the head and tail pointers should point to the same node.
Related
A steque is a stack-ended queue which is a data type that implements push, pop, and enqueue along with any other features that you wish to add to.
Note that I am implementing the steque with linked-list-based approach. Below is the code for my entire Steque class, the problem I have is whenever I try popping some element from the steque or to iterate through it I get the NullPointerException. The push() and enqueue() method seem to work just fine as I tested and I did thoroughly check my pop() and iterator() but can't seem to find any possible errors that might cause any NullPointerException. Any help on my code as how to resolve this will be greatly appreciated!
public class Steque<Item> implements Iterable<Item> {
private int N;
private Node first;
private Node last;
private class Node {
private Item item;
private Node next;
private Node prev;
}
/**
* create an empty steque
*/
public Steque() {
N = 0;
first = null;
last = null;
}
/**
* pop (return) the first item on top of stack and modify first
* accordingly to refer to next node.
*/
public Item pop() {
if (isEmpty()) throw new RuntimeException("Steque underflow");
Item item = first.item;
first = first.next;
N--;
return item;
}
/**
* push item on top of the stack and modify the first pointer
* to refer to the newly added item.
*/
public void push(Item item) {
Node oldfirst = first;
Node first = new Node();
first.item = item;
first.next = oldfirst;
if (oldfirst != null)
oldfirst.prev = first;
++N;
}
/**
* push item on bottom of the stack and reset the last pointer
* to refer to the newly added item.
*/
public void enqueue(Item item) {
Node oldlast = last;
Node last = new Node();
last.item = item;
last.prev = oldlast;
if (oldlast != null)
oldlast.next = last;
++N;
}
public Item peek() {
if (isEmpty()) throw new RuntimeException("Steque underflow");
return first.item;
}
public boolean isEmpty() {
return N == 0;
}
public int size() {
return N;
}
/**
* prints the steque from top to bottom
private void printState() {
System.out.println("Printing steque below: top --> bottom ");
for (Node idx = this.first; idx!= null; idx = idx.next) {
System.out.print(idx.item + " - ");
}
System.out.println();
}
*/
public String toString() {
StringBuilder s = new StringBuilder();
for (Item i : this) {
s.append(i + " ");
}
return s.toString().trim();
}
public Iterator iterator() {
return new LIFOIterator();
}
/**
* iterator that implements hasNext(), next(), and remove().
*/
private class LIFOIterator implements Iterator<Item>
{ // support LIFO iteration
private Node current = first;
public boolean hasNext() { return current.next != null; }
public void remove() {
Node n = first;
while (n.next.next != null) {
n = n.next;
}
n.next = null;
--N;
}
public Item next() {
if (!hasNext())
throw new NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
/**
* a simple test client
*/
public static void main(String[] args) {
Steque<String> steq = new Steque<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) {
//steq.push(item);
steq.enqueue(item);
}
/*
else if (!steq.isEmpty()) {
System.out.print(steq.pop() + " ");
}
*/
}
System.out.println("(" + steq.size() + " left on steque)");
Iterator itr = steq.iterator();
System.out.println("printing steque of strins below: ");
while(itr.hasNext()) {
System.out.print(itr.next() + " ");
}
}
}
Note: I am omitting all the import statements here but they are indeed included in my program so there is guaranteed to be no "undefined method" or "undeclared identifier" error in this code.
The problem is, that your first variable does not get filled when you only use the enqueue method.
Therefore the methods that access this field fire an NPE.
hasNext uses the field via current.
IMO the solution would be to catch the special for N == 0 in enqeue and fill the first element with the available element.
I tried
if(N==0)
first = last
after the initialisation of last in enqeue and it works without NPE.
Basically i'm trying to write a print statement that will allow me to print the elements per line as a println as the output when i run the driver.java. And for the life of me i cannot figure out how to do it. Any help will be appreciated.
here is the driver.java
public class Driver {
public static void main(String args[]){
LList<String> s_list = new LList<String>();
s_list.insert("New York, 8.4M");
s_list.insert("Los Angeles 3.8M");
s_list.insert("Chicago, 2.7M");
s_list.insert("Houston, 2.1M");
s_list.insert("Philadelphia, 1.55M");
s_list.insert("Phoenix, 1.51M");
s_list.append("San Antonio, 1.4M");
s_list.append("San Diego, 1.35M");
s_list.append("Dallas, 1.25M");
s_list.append("San Jose, 0.998M");
s_list.append("Austin, 0.88M");
s_list.append("Indianapolis, 0.84M");
s_list.append("Jacksonville, 0.84M");
s_list.append("San Francisco, 0.83M");
s_list.append("Columbus, 0.82M");
s_list.append("Charlotte, 0.79M");
s_list.print();
s_list.moveToPos(3);
s_list.remove();
s_list.print();
s_list.moveToEnd();
s_list.remove();
s_list.print();
s_list.moveToStart();
s_list.remove();
s_list.remove();
s_list.print();
s_list.clear();
s_list.print();
}
}
and I have a java file named LList.java
where I am trying to write a print method where it will print() function that prints the contents of each element of your list; print one element per line.
public void print {
}
So, How will i print the elements in "s_list" line per line as output.
Any help is appreciated.
UPDATE: I am going to post Llist.java,list.java & link.java here
Llist.java
/** Linked list implementation */
class LList<E> implements List<E> {
private Link<E> head; // Pointer to list header
private Link<E> tail; // Pointer to last element
protected Link<E> curr; // Access to current element
private int cnt; // Size of list
/** Constructors */
LList(int size) { this(); } // Constructor -- Ignore size
LList() {
curr = tail = head = new Link<E>(null); // Create header
cnt = 0;
}
/** Remove all elements */
public void clear() {
head.setNext(null); // Drop access to links
curr = tail = head = new Link<E>(null); // Create header
cnt = 0;
}
/** Insert "it" at current position */
public void insert(E it) {
curr.setNext(new Link<E>(it, curr.next()));
if (tail == curr) tail = curr.next(); // New tail
cnt++;
}
/** Append "it" to list */
public void append(E it) {
tail = tail.setNext(new Link<E>(it, null));
cnt++;
}
/** Remove and return current element */
public E remove() {
if (curr.next() == null) return null; // Nothing to remove
E it = curr.next().element(); // Remember value
if (tail == curr.next()) tail = curr; // Removed last
curr.setNext(curr.next().next()); // Remove from list
cnt--; // Decrement count
return it; // Return value
}
/** Set curr at list start */
public void moveToStart()
{ curr = head; }
/** Set curr at list end */
public void moveToEnd()
{ curr = tail; }
/** Move curr one step left; no change if now at front */
public void prev() {
if (curr == head) return; // No previous element
Link<E> temp = head;
// March down list until we find the previous element
while (temp.next() != curr) temp = temp.next();
curr = temp;
}
/** Move curr one step right; no change if now at end */
public void next()
{ if (curr != tail) curr = curr.next(); }
/** #return List length */
public int length() { return cnt; }
/** #return The position of the current element */
public int currPos() {
Link<E> temp = head;
int i;
for (i=0; curr != temp; i++)
temp = temp.next();
return i;
}
/** Move down list to "pos" position */
public void moveToPos(int pos) {
assert (pos>=0) && (pos<=cnt) : "Position out of range";
curr = head;
for(int i=0; i<pos; i++) curr = curr.next();
}
/** #return Current element value */
public E getValue() {
if(curr.next() == null) return null;
return curr.next().element();
}
public void print()
{
}
}
List.java
/** List ADT */
public interface List<E> {
/** Remove all contents from the list, so it is once again
empty. Client is responsible for reclaiming storage
used by the list elements. */
public void clear();
/** Insert an element at the current location. The client
must ensure that the list�s capacity is not exceeded.
#param item The element to be inserted. */
public void insert(E item);
/** Append an element at the end of the list. The client
must ensure that the list�s capacity is not exceeded.
#param item The element to be appended. */
public void append(E item);
/** Remove and return the current element.
#return The element that was removed. */
public E remove();
/** Set the current position to the start of the list */
public void moveToStart();
/** Set the current position to the end of the list */
public void moveToEnd();
/** Move the current position one step left. No change
if already at beginning. */
public void prev();
/** Move the current position one step right. No change
if already at end. */
public void next();
/** #return The number of elements in the list. */
public int length();
/** #return The position of the current element. */
public int currPos();
/** Set current position.
#param pos The position to make current. */
public void moveToPos(int pos);
/** #return The current element. */
public E getValue();
}
Link.java
/** Singly linked list node */
class Link<E> {
private E element; // Value for this node
private Link<E> next; // Pointer to next node in list
// Constructors
Link(E it, Link<E> nextval)
{ element = it; next = nextval; }
Link(Link<E> nextval) { next = nextval; }
Link<E> next() { return next; } // Return next field
Link<E> setNext(Link<E> nextval) // Set next field
{ return next = nextval; } // Return element field
E element() { return element; } // Set element field
E setElement(E it) { return element = it; }
}
We will need to see inside the class of LList.java... but for now i am going to assume LList extends List [or ArrayList, etc..]
public void print
{
for(int i = 0; i < this.size(); i++) //this really depends on how you store your list
System.out.println(this.get(i));
}
This all depends on how your LList.java looks though... [this.size()] refers to the List or ArrayList class [if you extended it...].
If you are not extending List or something along those lines, you could always do:
public void print
{
for(int i = 0; i < storingArray.size(); /*or .length*/ i++)
System.out.println(storingArray.get(i)); /*or storingArray[i]*/
}
But as always, you could take the easy way and just do:
list.foreach(System.out::println); //must have Java 8.
Revised Answer based on your comments:
public void print() {
Link<E> currentNode = head; //Sets starting node to first node in list
while (currentNode != tail) { //Checks if current node is equal to last node
System.out.println(currentNode.element()); //Prints currentNodes's element
currentNode = currentNode.next(); //Sets currentNode to next node in list
}
System.out.println(tail.element()); //Prints last node in list
}
Note: Some of your comments in you Link<E>code don't match what your functions are actually doing.
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.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I am working on some code in Java that is supposed to implement the well-known
Josephus problem using a Circular Linked List. Here is some information on the Josephus
problem: http://en.wikipedia.org/wiki/Josephus_problem
I have a Student class and Driver class that have been given to me to create my Josephus class.
Here is the Student class: http://pastebin.com/4YgSA7CM
Here is the Driver class: http://pastebin.com/Nb08Dtqk
Neither of these classes can be modified.
I had to start from scratch and make a Josephus class that uses a Circular Linked List that effectively uses the Josephus problem.
Here is my completed Josephus class with no compiler errors:
/** Implementation of Josephus problem. The Josephus problem
is named after the historian Flavius Josephus. For more
information on this problem visit:
http://en.wikipedia.org/wiki/Josephus_problem
*/
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.ArrayList;
public class Josephus <E> {
private Node<E> head;
private int count; // number of elements in the list
/** Constructs an empty Josephus circle */
// Complexity O(1)
public Josephus() {
head = null;
count = 0;
}
/** Constructs an Josephus circle by adding the
elements from an arraylist
#param array The ArrayList of items of type E
*/
// Complexity: O(n)
public Josephus(ArrayList<E> array) {
head = null;
for (int i = 0; i < array.size(); i++)
add(array.get(i));
}
/** Inserts the specified element in the list at the
last position
#param dataItem the element to add
*/
// Complexity O(1)
#SuppressWarnings({ "unchecked" })
public void add(E dataItem) {
Node <E> node = new Node <E> (dataItem, null, null);
if (count == 0) // list is empty
head = node.previous= node ;
else
head.previous.next = node;
node.previous = head.previous;
head.previous = node;
count++;
}
// To be completed by the student
/** Inserts the specified element in the list at the
end. This method has the same behavior as add(E)
#param dataItem the element to add at the end
*/
// Complexity O(1)
public void addLast(E dataItem) {
add(dataItem);
}
/** Inserts the element at the beginning of the list
#param dataItem The element to be added
*/
// Complexity O(1)
public void addFirst(E dataItem) {
Node<E> node = new Node <E>(dataItem, null, null);
// To be completed by the student
if (head == null) // list is empty
head = head.previous = node;
else {
node.next = head;
head.previous = node;
head = node;
}
count++;
}
/** removes the element from the beginning of the list
#return The element that was remvoed
#throws NoSuchElementException if the list is empty
*/
// Complexity O(1)
public E removeFirst() {
// To be completed by the student
if (head != null) {
E item = head.data;
if (head == head.previous) // list has only one element
head = head.previous = null;
else { // list has more than 1 element
head = head.next;
head.previous = null;
}
count--;
return item;
}
else throw new NoSuchElementException();
}
/** removes the element from the end of the list
#return The element that was remvoed
#throws NoSuchElementException if the list is empty
*/
// Complexity O(1)
public E removeLast() {
// to be completed by the student
if (head.previous != null) {
E item = head.previous.data;
if (head == head.previous) // list has only one item
head = head.previous = null;
else { // list has more than one element
head.previous = (head.previous).previous;
head.previous.next = null;
}
count--;
return item;
}
else throw new NoSuchElementException();
}
/** returns a reference to the element at
position index
#param index The index of the element being sought
#return A reference to the element at position index
#throws IndexOutOfBoundsException if index is out of range
*/
// Complexity O(n)
public E get(int index) {
if ((index < 0) || (index >= count))
throw new IndexOutOfBoundsException(Integer.toString(index));
Node<E> temp = head;
for (int i = 0; i < index; i++)
temp = temp.next;
return temp.data;
}
/** Sets the element at position index to reference
anEntry.
#param index The position of the element that is to
be set
#param anEntry The new value at position index
#return the element that was previously at position index
#throws IndexOutOfBoundsException if index is out of range
*/
// Complexity O(n)
public E set(int index, E anEntry) {
if ((index < 0) || (index >= count))
throw new IndexOutOfBoundsException(Integer.toString(index));
Node<E> temp = head;
for (int i = 0; i < index; i++)
temp = temp.next;
E result = temp.data;
temp.data = anEntry;
return result;
}
/** Inserts the specified element in the list at a
given index
#param index The position at which the new element
has to be inserted
#param anEntry The element to add
#throws IndexOutOfBoundsException if index is out of range
*/
// Complexity O(n)
public void add(int index, E anEntry) {
// To be completed by the student
if ((index < 0) || (index > count))
throw new IndexOutOfBoundsException(Integer.toString(index));
if (index == 0) addFirst(anEntry);
else if (index == count) addLast(anEntry);
else {
Node <E> node = head;
int i = 0;
while(node!=null && i<index){
i++;
node = node.next;
}
Node<E> newNode = new Node <E> (anEntry, node, node.next);
node.next.previous = newNode;
node.next = newNode;
count++;
}
}
/** searches for target and returns the position of the
first occurrence, or -1 if it is not in the list
#param target The element we are searching for
#return The position of target if found; -1 if not found
*/
// Complexity O(n)
public int indexOf(E target) {
Node<E> temp = head;
for (int i = 0; i < count; i++) {
if (temp.data.equals(target)) return i;
temp = temp.next;
}
return -1;
}
/** removes the element at position index
#param index The index of the element to be removed
#return The element that was removed
#throws IndexOutOfBoundsException if index is invalid
*/
// Complexity O(n)
public E remove(int index) {
// to be completed by the student
if ((index < 0) || (index >= count))
throw new IndexOutOfBoundsException(Integer.toString(index));
Node<E> temp = head;
for(int i =0;i<index; i++)
temp = temp.next;
E result = temp.data;
temp.next = temp.previous;
return result;
}
/** sets the start position for the Josephus game
#param index The starting position
#throws IndexOutOfBoundsException if index is invalid
*/
// Complexity O(n)
public void setStartPosition(int index) {
if ((index < 0) || (index >= count))
throw new IndexOutOfBoundsException(Integer.toString(index));
for (int i = 0; i < index; i++)
head = head.next;
}
/* This private utility method is used in startJosephus
method.
Complexity O(1)
*/
private void removeAfter(Node<E> node) {
node.next = node.next.next;
node.next.previous = node;
count--;
}
/** simulates the Josephus game by killing every other person
until the winner is the only one left.
#return The survivor of the game
*/
public E startJosephus() {
E item =head.data;
if(head.next != null){
if(head == head.previous)
return item;
else
while(count>1);
removeAfter(head);
head =head.next;
}
return item;
}
/** Returns a list-iterator of the elements in this list
(in proper sequence), starting at the beginning
of the list.
*/
public ListIterator <E> iterator() {
return new myIterator();
}
/** #return The number of elements in the list
*/
public int size() {
return count;
}
// this is an inner clss implementing the ListIterator
// interface.
// visit http://docs.oracle.com/javase/1.4.2/docs/api/java/util/ListIterator.html
// for a complete list of methods in ListIterator
private class myIterator implements ListIterator <E> {
private Node<E> forward = head;
private Node<E> backward = head;
private boolean firstTime = true;
/** checks if a current item E is the last
in the collection
*/
public boolean hasNext() {
return (forward != null);
}
/** returns the next item in the collection if
there is one. If there is no more items
throws NoSuchElementException
*/
public E next() {
if (forward == null) throw
new NoSuchElementException();
else {
E item = forward.data;
forward = forward.next;
if (forward == head) forward = null;
return item;
}
}
/** checks if a current item is the first
in the collection
*/
public boolean hasPrevious() {
return (backward != null);
}
/** returns the previous item in the collection if
there is one. If there is no more items
throws NoSuchElementException
*/
public E previous() {
if (backward == null) throw
new NoSuchElementException();
else {
if (firstTime) {
backward = backward.previous;
firstTime = false;
}
E item = backward.data;
backward = backward.previous;
if (backward == head.previous) backward = null;
return item;
}
}
/* this operation is not supported */
public void add(E obj) {
throw new UnsupportedOperationException();
}
/* this operation is not supported */
public void set(E obj) {
throw new UnsupportedOperationException();
}
/* this operation is not supported */
public int previousIndex() {
throw new UnsupportedOperationException();
}
/* this operation is not supported */
public int nextIndex() {
throw new UnsupportedOperationException();
}
/* this operation is not supported */
public void remove() {
throw new UnsupportedOperationException();
}
}
private static class Node <E> {
private E data;
private Node<E> next;
private Node<E> previous;
/** constructor Creates an empty node with both next and
previous fields set to be null
#param dataItem - item to be inserted
*/
private Node(E dataItem) {
data= dataItem;
previous = next = null;
}
/** creates a new node that references another node
#param dataItem The data stored
#param previousNodeRef The node previous to this node
#param nextNodeRef The node next to this node
*/
private Node(E dataItem, Node<E> previousNodeRef, Node <E> nextNodeRef ) {
data = dataItem;
previous = previousNodeRef;
next = nextNodeRef;
}
}
}
My startJosephus method is the main problem I believe. Not completely sure though. Here is the startJosephus method specifically within that above code:
/** simulates the Josephus game by killing every other person
until the winner is the only one left.
#return The survivor of the game
*/
public E startJosephus() {
E item =head.data;
if(head.next != null){
if(head == head.previous)
return item;
else
while(count>1);
removeAfter(head);
head =head.next;
}
return item;
}
Here is what is running when I run my Josephus class: http://pastebin.com/5GnChgYd
Here is what the output is supposed to produce: http://pastebin.com/Qr5dCZJp
Also, here are the two input files used to produce this output:
StudentList1.txt: http://pastebin.com/ysjevQ8u
StudentList2.txt: http://pastebin.com/r2YeppNm
Based on the output I am getting and the output I am supposed to be getting, it appears the Josephus problem is not starting and simulating the killing spree. However, I do not know what is wrong with my code. My code cannot have a tail since it is a Circular Linked List. Any idea as to what I am doing wrong here? Sorry for all the Pastebin links, it just seemed like a better way to organize all of the code I am presenting here. Hope to hear your thoughts.
EDIT:
There are 21 persons in this list
The game starts with McElroy,Breanna at starting position
The killing spree begins......
The sole survivor at the end of this gruesome game is McElroy,Breanna
Exception in thread "main" java.lang.NullPointerException
at Josephus$Node.access$5(Josephus.java:383)
at Josephus.add(Josephus.java:49)
at Josephus.addLast(Josephus.java:66)
at Driver.main(Driver.java:96)
This is the new runtime errors I am getting after I fixed my problem with the infinite loop. Any suggestions???? What is with all of these Null Pointer Exceptions
if(head.next != null) {
if (head == head.previous)
return item;
else
while(count>1);
removeAfter(head);
head =head.next;
This piece of code will loop forever in all cases except when head.next is null or head == head.previous, which will always be true at the start of the game. Therefore, your program loops forever for anything but the trivial initial conditions. Obviously, you intended to write
if(head.next != null) {
if (head == head.previous)
return item;
else
while(count>1) {
removeAfter(head);
head =head.next;
}
I think you have an endless loop:
while (count > 1);
Recently, my class has been studying ArrayLists and LinkedLists. This past week we received an assignment that asked us to create push and pop methods within our LinkedList stack class. I understand the logic behind stacks such that it's last-in-first-out, but I am having trouble with the actual code. I am fairly new to computer science (this being my second course ever) and this particular assignment is literally causing me to pull my hair out. I already turned this assignment in, but we have a midterm next week and I would like to do well on it. I have been all over the web and my textbook looking for help, but nothing. My professor only refers me to the TA and the TA is only concerned with helping me with the logic, not the actual code. I'll post the instructions my professor gave me below, as well as my code so far. Thanks in advance.
From the professor:
Implement stacks using the template given in the following Java
files:
CS401StackInterface.java CS401StackLinkedListImpl.java
public interface CS401StackInterface<E>
{
/**
* Get the top element on the stack.
*
* #return the first element on the stack.
*/
public E pop();
/**
* Adds an element on the top of the stack.
*
* #param e - The element to be added to the stack.
*/
public void push(E e);
/**
* Determines the number of elements in this data structure.
*
* #return the number of elements currently resident in this
* data structure.
*/
public int size();
}
Here is the actual class where I attempt to define my methods:
public class CS401StackLinkedListImpl<E> implements CS401StackInterface<E>
{
private LinkEntry<E> head;
private int num_elements;
public CS401StackLinkedListImpl()
{
head = null;
num_elements = 0;
}
public void setElement(LinkEntry<E> anElement){
head = anElement;
}
/*Append the new element to the end of the list*/
public void push(E e)
{
LinkEntry<E> temp = new LinkEntry<E>();
temp.element = e;
temp.next = head;
head = temp;
}
/*Remove the most recently pushed element at the end of the list*/
public E pop()
{
head.next = head;
num_elements--;
return (E) head;
}
public int size()
{
LinkEntry<E> temp = new LinkEntry<E>();
for (temp = head; head != null; head = head.next)
num_elements++;
return num_elements;
}
public String toString()
{
String string = "";
LinkEntry<E> temp = new LinkEntry<E>();
for (temp = head; temp != null; temp = temp.next)
{
string += temp.element.toString() + "";
}
return string;
}
/* ------------------------------------------------------------------- */
/* Inner classes */
protected class LinkEntry<E>
{
protected E element;
protected LinkEntry<E> next;
protected LinkEntry() { element = null; next = null; }
}
}
Finally, here is my main class where I test my methods:
import java.util.*;
public class App {
public static <E> void main(String[] args) {
CS401StackLinkedListImpl<String> my_stack = new CS401StackLinkedListImpl<String>();
my_stack.push("Brian");
my_stack.push("Chris");
my_stack.push("Joe");
System.out.println("Stack size: " + my_stack.size());
my_stack.pop();
System.out.println("Stack size: " + my_stack.size());
my_stack.toString();
}
}
When I run my main class this is what it returns:
Stack size: 3
Exception in thread "main" java.lang.NullPointerException
at week6.CS401StackLinkedListImpl.pop(CS401StackLinkedListImpl.java:30)
at week6.App.main(App.java:66)
Everything I've come across just tells me to create a new Stack, which is easy because then I don't have to worry about the "innards" of the code, but that's not what I need. Thanks.
The problem is with your size method. It corrupts the value of head so that it is null. Then your call to pop gets an NPE.
You also have a problem with variable initialization - num_elements will just increase on every call to size. You can simplify this by increasing the variable on calls to push.
Also your setElement will corrupt your stack, if used, because it just sets head, without patching up the next pointers.
Sorry, I see that this is turned in homework... so here are some concrete ways to correct the code:
public CS401StackLinkedListImpl()
{
head = null;
num_elements = 0;
}
public void setElement(LinkEntry<E> anElement)
{
if (head != null)
anElement.next = head.next; //New top-of-stack needs to point to next element, if any
else
anElement.next = null;
head = anElement;
}
/*Append the new element to the end of the list*/
public void push(E e)
{
LinkEntry<E> temp = new LinkEntry<E>();
temp.element = e;
temp.next = head;
head = temp;
num_elements++; // Increase number of elements count here
}
/*Remove the most recently pushed element at the end of the list*/
public E pop()
{
E result = head.element; // Save return value of TOS
head = head.next; // Corrected POP action
num_elements--;
return result;
}
public int size()
{
//Remove below since count is kept accurate with push/pop methods
//LinkEntry<E> temp = new LinkEntry<E>();
//for (temp = head; head != null; head = head.next)
// num_elements++;
return num_elements;
}
You might want to add an addition check in pop to throw a better exception than NPE if there are no elements, such as:
if (head == null)
throw new StackUnderflowException(); // and define a StackUnderflowException; or use a standard exception with a message
public void push(E e)
It seems ok.
public E pop()
It doensn't seem ok: you assign to the head.next element itself, this creates a loop. Then you return the actual head. You should first save current head somewhere, then update head reference to the next element and return the previous head.
public int size()
Method is wrong: first of all you instantiate a useless element to temp but you don't need it (since you will use the temp inside the loop and you should initialize it to the current head. Then check your for loop: you are using head either in the stop condition either in the end of loop iteration. You should never use head, since you are just iterating on the list and not modifying it, but just temp (check your toString code which appears to be correct).
looking at the code, it appears your Pop method is backwards.
In your push method, you assign the current head element to the 'next' attribute of the new LinkEntry, and then make that the new head. Therefor, when you pop the item off the list, you need to assign the 'next' element back to the head of the list. so your code, which is:
head.next = head;
should be:
LinkEntry<E> toReturn = head;
head = head.next;
return toReturn.element;
In effect, you are cloning the head reference to the current item at the top of the stack (so you can return it), then moving the head reference to point to the next item in the stack
/*Append the new element to the end of the list*/
public void push(E e)
{
LinkEntry<E> temp = new LinkEntry<E>();
temp.element = e;
temp.next = head;
num_elements++;//Increment count<--- Correction
head = temp;
}
/*Remove the most recently pushed element at the end of the list*/
public E pop()
{
E returnValue =head.element ;<--- Correction
head=head.next;<--- Correction
num_elements--;//Decrement count
return returnValue;
}
public int size()
{
return num_elements;<--- Correction
}