Java Linked List Sequence insertFirst method inserts object twice - java

I am trying to implement a Linked List Sequence in Java however my method for inserting an object at the start of the sequence inserts the object twice and I don't understand why.
If anyone can help it would be really appreciated.
The current output of my test program is
30
30
but I want it to be 30
Thanks in advance
Below is the code for the sequence and the method for insertFirst
public class Sequence implements SequenceInterface{
private Node listHead;
private Node listTail;
protected class Node{
protected Object datum;
protected Node next;
public Node(Object o, Node n) {
datum = o;
next = n;
}
}
//Constructor
public Sequence(){
listHead = null;
listTail = null;
}
public void insertFirst(Object o) {
if(listHead == null){
listHead = new Node(o, listTail);
listTail = listHead;
}else{
Node oldLH = listHead;
listHead = new Node(o, oldLH);
}
}
}
Here is my test program
public class SequenceTest {
/**
* #param args
* #throws Exception
*/
public static void main(String[] args) throws Exception {
Sequence s = new Sequence();
s.insertFirst(new Integer(30));
for(int i=0; i<2; i++){
System.out.println(s.element(i));
}
}
}

It looks like it is only added once, but is being printed twice.
If you unroll the loop:
for(int i=0; i<2; i++){
System.out.println(s.element(i));
}
you essentially get:
System.out.println(s.element(0));
System.out.println(s.element(1));
so if this is unexpected behaviour, what we really need to look at to diagnose it is the element() method.
What do you want to happen when s.element(2) is called and 's' only contains one element? Should it throw an index out of range exception? Should it wrap or crop to within range when it is indexed past the lists range (presumably the current behaviour)?

Assuming you are trying to create a singly linked list, you've got this backwards:
listHead = new Node(o, listTail);
listTail = listHead;
When you execute that, you are assigning the new node to both listHead and listTail. You should have
listTail = listHead;
listHead = new Node(o, listTail);

public void insertFirst(Object o) {
Node newNode = new Node(o, listHead);
if (listHead == null) {
listHead = newNode;
listTail = listHead;
} else {
listHead = newNode;
}
}

This is the final version tested that works perfectly! Hope this helps:
class SequenceDLListException extends Exception {
SequenceDLListException() {
super();
}
SequenceDLListException(String s) {
super(s);
}
}
/**
* <dl>
* <dt>Purpose: Implementation of Sequence ADT.
* <dd>
*
* <dt>Description:
* <dd>This class is an implementation of the Sequence using an linked list as
* the underlying data structure. The capacity is therefore unlimited and
* overflow does not need to be checked.
* </dl>
*
*
* #version $Date: 2015/01/30
*/
public class SequenceDLList {
/**
* Member class Node encapsulates the nodes of the linked list in
* which the stack is stored. Each node contains a data item and a
* reference to another node - the next in the linked list.
*
*
*/
public Node lastNode() {
return listTail;
}
public Node firstNode() {
return listHead;
}
protected class Node {
public Node(Object o) {
this(o, null, null);
}
/**
* I added another null because it has to point at the beginning and at the end
* to some kind of terminator to facilitate the traversal of the list
*/
public Node(Object o, Node p, Node n) {
datum = o;
prev =p;
next = n;
}
/**
* I added another Node because every node has two links now with the Doubly Linked List
*/
//The Node data structure consists of two object references.
//One for the datum contained in the node and the other for
//the next node in the list.
protected Object datum;
protected Node next;
protected Node prev;
}
//We use object references to the head and tail of the list (the head
//and tail of the sequence, respectively).
private Node listHead;
private Node listTail;
//Only require a single constructor, which sets both object
//references to null.
/**
* Constructs an empty sequence object.
*/
public SequenceDLList() {
listHead = null;
listTail = null;
}
/**
* Adds a new item at the start of the sequence.
*/
public void insertFirst(Object o) {
//There is a special case when the sequence is empty.
//Then the both the head and tail pointers needs to be
//initialized to reference the new node.
if (listHead == null) {
listHead = new Node(o, listHead, null);
listTail = listHead;
}
//In the general case, we simply add a new node at the start
//of the list via the head pointer.
else {
listHead = new Node(o, listHead, null);
}
}
/**
* Adds a new item at the end of the sequence.
*/
public void insertLast(Object o) {
//There is a special case when the sequence is empty.
//Then the both the head and tail pointers needs to be
//initialized to reference the new node.
if (listHead == null) {
listHead = new Node(o, listHead, null);
listTail = listHead;
}
//In the general case, we simply add a new node to the end
//of the list via the tail pointer.
else {
listTail.next = new Node(o, listTail, null);
listTail = listTail.next;
}
}
/**
* Adds a new item at a specified position in the sequence.
*/
public void insert(Object o, int index) throws SequenceDLListException {
//Check the index is positive.
if (index < 0) {
throw new SequenceDLListException("Indexed Element out of Range");
}
//There is a special case when the sequence is empty.
//Then the both the head and tail pointers needs to be
//initialized to reference the new node.
if (listHead == null) {
if (index == 0) {
listHead = new Node(o, listHead, null);
listTail = listHead;
} else {
throw new SequenceDLListException("Indexed element is out of range");
}
}
//There is another special case for insertion at the head of
//the sequence.
else if (index == 0) {
listHead = new Node(o, listHead, null);
}
//In the general case, we need to chain down the linked list
//from the head until we find the location for the new
//list node. If we reach the end of the list before finding
//the specified location, we know that the given index was out
//of range and throw an exception.
else {
Node nodePointer = listHead;
int i = 1;
while (i < index) {
nodePointer = nodePointer.next;
i += 1;
if (nodePointer == null) {
throw new SequenceDLListException("Indexed Element out of Range");
}
}
Node newNode = new Node(o, nodePointer, nodePointer.next);
if (nodePointer.next != null) {
nodePointer.next.prev = newNode;
}
//Now we've found the node before the position of the
//new one, so we 'hook in' the new Node.
nodePointer.next = newNode;
//Finally we need to check that the tail pointer is
//correct. Another special case occurs if the new
//node was inserted at the end, in which case, we need
//to update the tail pointer.
if (nodePointer == listTail) {
listTail = newNode;
}
}
}
/**
* Removes the item at the start of the sequence.
*/
public void deleteFirst() throws SequenceDLListException {
//Check there is something in the sequence to delete.
if (listHead == null) {
throw new SequenceDLListException("Sequence Underflow");
}
//There is a special case when there is just one item in the
//sequence. Both pointers then need to be reset to null.
if (listHead.next == null) {
listHead = null;
listTail = null;
}
//In the general case, we just unlink the first node of the
//list.
else {
listHead = listHead.next;
listHead.prev = null;
}
}
/**
* Removes the item at the end of the sequence.
*/
public void deleteLast() throws SequenceDLListException {
//Check there is something in the sequence to delete.
if (listHead == null) {
throw new SequenceDLListException("Sequence Underflow");
}
//There is a special case when there is just one item in the
//sequence. Both pointers then need to be reset to null.
if (listHead.next == null) {
listHead = null;
listTail = null;
}
//In the general case, we need to chain all the way down the
//list in order to reset the link of the second to last
//element to null.
else {
Node nodePointer = listHead;
while (nodePointer.next != listTail) {
nodePointer = nodePointer.next;
}
//Unlink the last node and reset the tail pointer.
nodePointer.next = null;
listTail = nodePointer;
}
}
/**
* Removes the item at the specified position in the sequence.
*/
public void delete(int index) throws SequenceDLListException {
//Check there is something in the sequence to delete.
if (listHead == null) {
throw new SequenceDLListException("Sequence Underflow");
}
//Check the index is positive.
if (index < 0) {
throw new SequenceDLListException("Indexed Element out of Range");
}
//There is a special case when there is just one item in the
//sequence. Both pointers then need to be reset to null.
if (listHead.next == null) {
if (index == 0) {
listHead = null;
listTail = null;
} else {
throw new SequenceDLListException("Indexed element is out of range.");
}
}
//There is also a special case when the first element has to
//be removed.
else if (index == 0) {
deleteFirst();
}
//In the general case, we need to chain down the list to find
//the node in the indexed position.
else {
Node nodePointer = listHead;
int i = 1;
while (i < index) {
nodePointer = nodePointer.next;
i += 1;
if (nodePointer.next == null) {
throw new SequenceDLListException("Indexed Element out of Range");
}
}
//Unlink the node and reset the tail pointer if that
//node was the last one.
if (nodePointer.next == listTail) {
listTail = nodePointer;
}
//When we remove the node we have to change the reference as well!
if (nodePointer.next.next != null) {
nodePointer.next.next.prev = nodePointer;
}
nodePointer.next = nodePointer.next.next;
}
}
/**
* Returns the item at the start of the sequence.
*/
public Object first() throws SequenceDLListException {
if (listHead != null) {
return listHead.datum;
} else {
throw new SequenceDLListException("Indexed Element out of Range");
}
}
/**
* Returns the item at the end of the sequence.
*/
public Object last() throws SequenceDLListException {
if (listTail != null) {
return listTail.datum;
} else {
throw new SequenceDLListException("Indexed Element out of Range");
}
}
/**
* Returns the item at the specified position in the sequence.
*/
public Object element(int index) throws SequenceDLListException {
//Check the index is positive.
if (index < 0) {
throw new SequenceDLListException("Indexed Element out of Range");
}
//We need to chain down the list until we reach the indexed
//position
Node nodePointer = listHead;
int i = 0;
while (i < index) {
if (nodePointer.next == null) {
throw new SequenceDLListException("Indexed Element out of Range");
} else {
nodePointer = nodePointer.next;
i += 1;
}
}
return nodePointer.datum;
}
/**
* Tests whether there are any items in the sequence.
*/
public boolean empty() {
return (listHead == null);
}
/**
* Returns the number of items in the sequence.
*/
public int size() {
//Chain down the list counting the elements
Node nodePointer = listHead;
int size = 0;
while (nodePointer != null) {
size += 1;
nodePointer = nodePointer.next;
}
return size;
}
/**
* Empties the sequence.
*/
public void clear() {
listHead = null;
listTail = null;
}
}

Related

Counting frequency of words - linked list

I am trying to insert words into a linked list because I want to count the number of times a word appears in the list and then return the words in the order of highest frequency to lowest. However, I keep getting an assertion error. Here are my insert, getCount, and getWords methods. It seems like insert and getCount are giving me problems.
public class Frequency<E extends Comparable<E>> implements Iterable<E>{
private Node first; //starting node
private Node parent; //parent of currently processed node
private int N; //number of words
/**
* Linked List Node
*/
private class Node{
private E key;
private int count;
private Node next;
Node(E e){
key = e;
count = 1;
next = null;
}
Node(E e, Node r){
key = e;
count = 1;
next = r;
}
#Override
public String toString(){
return "("+key +","+count+")";
}
}
/**
* Inserts a word into linked list
* #param key to be inserted
* #return true if the key is inserted successfully.
*/
public boolean insert(E key){
if (first == null || first.key != key) {
first = new Node(key, first);
} else {
Node curr = first;
while (curr.next != null) {
curr.next = new Node(key, first.next);
}
curr = curr.next;
N++;
}
return true;
}
/**
*
* #param key is the key to be searched for
* #return frequency of the key. Returns -1 if key does not exist
*
*/
public int getCount(E key){
// go through the linked list and count the number of times each word appears
// return the count of the word that is being called.
if (key == null) {
return -1;
}
int N = 0;
Node curr = first;
while (curr != null) {
if (curr.key.equals(key)) {
N++;
}
curr = curr.next;
}
return N;
}
/**
* Returns the first n words and count
* #param n number of words to be returned
* #return first n words in (word, count) format
*/
public String getWords(int n){
Node curr = first;
for (int i = 1; i < n; i++) {
curr = curr.next;
}
return curr.toString();
}
/**
* Frequency List iterator
*/
#Override
public Iterator<E> iterator() {
return new FreqIterator();
}
/**
*
* Frequency List iterator class
*
*/
private class FreqIterator implements Iterator<E>{
#Override
public boolean hasNext() {
Node curr = first;
if(curr != null) {
return true;
}
return false;
}
#Override
public E next() {
Node curr = first;
if(hasNext() == false) {
return null;
}
E item = curr.key;
curr = curr.next;
return item;
}
}
}
EDIT
This is my test to insert the same word twice into a linked list. I want the result to be 2, but I am actually getting 1. I'm assuming it has to do with my insert method.
#Test
public void testInsert() {
Frequency<String> freq = new Frequency<>();
freq.insert("dog");
freq.insert("dog");
String answer = freq.getWords(1);
assertEquals("(dog,2)", answer);
}
It doesn't work because in your getCount(E key) you never check if the key passed in is equal to the curr node while iterating through it.
Make this minor alteration to the method:
public int getCount(E key) {
if (key == null) {
return -1;
}
int N = 0;
Node curr = first;
while (curr != null) {
if (curr.key.equals(key)) { // change made here
N++;
}
curr = curr.next;
}
return N;
}
As per the edit, there is a logic error in the insert(E key). You need to iterate to find the last element in the list and then assign the next reference to the newly created node.
public boolean insert(E key) {
if (first == null || first.key != key) {
first = new Node(key, first);
} else {
Node curr = first;
while (curr.next != null) { // iterate till the end of the list
curr = curr.next;
}
curr.next = new Node(key); // point last node's next ref to new node
N++;
}
return true;
}

Initializing linked list

When I run my driver class, my list wont initialize. This is what should be necessary to start the list.
public class SortedListReferenceBased implements ListInterface {
private Node head;
private int numItems; // number of items in list
public SortedListReferenceBased()
// creates an empty list
{
head = new Node(null);
numItems = 0;
} // end default constructor
public boolean isEmpty()
// Determines whether a list is empty
{
return true;
} // end isEmpty
public int size()
// Returns the number of items that are in a list
{
return numItems;
} // end size
public void removeAll()
// Removes all the items in the list
{
head = null;
numItems = 0;
} // end removeAll
public Object get(int index) throws ListIndexOutOfBoundsException
// Retrieves the item at position index of a sorted list, if 0 <= index <
// size().
// The list is left unchanged by this operation.
// Throws an exception when index is out of range.
{
if (index < 0 || index >= numItems) {
throw new ListIndexOutOfBoundsException(index + " is an invalid index");
}
return new Object();
}
public void add(Object item) throws ListException
// Inserts item into its proper position in a sorted list
// Throws an exception if the item connot be placed on the list
{
try {
Node newNode = new Node(item);
if (head != null) {
int i = locateIndexToAdd(item);
if (i >= -1 && i <= numItems) {
add(i, item);
}
} else {
head = new Node(newNode);
Node curr = head.getNext();
curr.setNext(null);
numItems++;
}
} catch (Exception e) {
throw new ListException("Add to List failed: " + e.toString());
}
}
}
The problem seems to be this part of your add method:
head = new Node(newNode);
Node curr = head.getNext();
curr.setNext(null);
numItems++;
I assume the next variable in Node gets initialized with null so head.getNext() returns null for curr. When you then call curr.setNext(null) you get a NullPointerException. Since this add the first entry in your list you want to set the next for your first element to null.
Also you do not have to wrap newNode in a Node since its already a node.
head = newNode;
head.setNext(null);
numItems++;
But since you initialize it with null anyway you don't have to do anything.
head = newNode;
numItems++;

Convert singly linked list to a doubly linked list using java

I understand the concept of LinkedList, and single/doubly linked list. I, however don't understand how to implement it to my code?
I have to convert this singly list to a doubly linked list:
public class MyLinkedList<E> extends MyAbstractList<E> {
private Node<E> head, tail;
/** Create a default list */
public MyLinkedList() {
}
/** Create a list from an array of objects */
public MyLinkedList(E[] objects) {
super(objects);
}
/** Return the head element in the list */
public E getFirst() {
if (size == 0) {
return null;
}
else {
return head.element;
}
}
/** Return the last element in the list */
public E getLast() {
if (size == 0) {
return null;
}
else {
return tail.element;
}
}
/** Add an element to the beginning of the list */
public void addFirst(E e) {
Node<E> newNode = new Node<E>(e); // Create a new node
newNode.next = head; // link the new node with the head
head = newNode; // head points to the new node
size++; // Increase list size
if (tail == null) // the new node is the only node in list
tail = head;
}
/** Add an element to the end of the list */
public void addLast(E e) {
Node<E> newNode = new Node<E>(e); // Create a new for element e
if (tail == null) {
head = tail = newNode; // The new node is the only node in list
}
else {
tail.next = newNode; // Link the new with the last node
tail = tail.next; // tail now points to the last node
}
size++; // Increase size
}
#Override /** Add a new element at the specified index
* in this list. The index of the head element is 0 */
public void add(int index, E e) {
if (index == 0) {
addFirst(e);
}
else if (index >= size) {
addLast(e);
}
else {
Node<E> current = head;
for (int i = 1; i < index; i++) {
current = current.next;
}
Node<E> temp = current.next;
current.next = new Node<E>(e);
(current.next).next = temp;
size++;
}
}
/** Remove the head node and
* return the object that is contained in the removed node. */
public E removeFirst() {
if (size == 0) {
return null;
}
else {
Node<E> temp = head;
head = head.next;
size--;
if (head == null) {
tail = null;
}
return temp.element;
}
}
/** Remove the last node and
* return the object that is contained in the removed node. */
public E removeLast() {
if (size == 0) {
return null;
}
else if (size == 1) {
Node<E> temp = head;
head = tail = null;
size = 0;
return temp.element;
}
else {
Node<E> current = head;
for (int i = 0; i < size - 2; i++) {
current = current.next;
}
Node<E> temp = tail;
tail = current;
tail.next = null;
size--;
return temp.element;
}
}
#Override /** Remove the element at the specified position in this
* list. Return the element that was removed from the list. */
public E remove(int index) {
if (index < 0 || index >= size) {
return null;
}
else if (index == 0) {
return removeFirst();
}
else if (index == size - 1) {
return removeLast();
}
else {
Node<E> previous = head;
for (int i = 1; i < index; i++) {
previous = previous.next;
}
Node<E> current = previous.next;
previous.next = current.next;
size--;
return current.element;
}
}
#Override /** Override toString() to return elements in the list */
public String toString() {
StringBuilder result = new StringBuilder("[");
Node<E> current = head;
for (int i = 0; i < size; i++) {
result.append(current.element);
current = current.next;
if (current != null) {
result.append(", "); // Separate two elements with a comma
}
else {
result.append("]"); // Insert the closing ] in the string
}
}
return result.toString();
}
#Override /** Clear the list */
public void clear() {
size = 0;
head = tail = null;
}
#Override /** Return true if this list contains the element e */
public boolean contains(E e) {
System.out.println("Implementation left as an exercise");
return true;
}
#Override /** Return the element at the specified index */
public E get(int index) {
System.out.println("Implementation left as an exercise");
return null;
}
#Override /** Return the index of the head matching element in
* this list. Return -1 if no match. */
public int indexOf(E e) {
System.out.println("Implementation left as an exercise");
return 0;
}
#Override /** Return the index of the last matching element in
* this list. Return -1 if no match. */
public int lastIndexOf(E e) {
System.out.println("Implementation left as an exercise");
return 0;
}
#Override /** Replace the element at the specified position
* in this list with the specified element. */
public E set(int index, E e) {
System.out.println("Implementation left as an exercise");
return null;
}
#Override /** Override iterator() defined in Iterable */
public java.util.Iterator<E> iterator() {
return new LinkedListIterator();
}
private void checkIndex(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException
("Index: " + index + ", Size: " + size);
}
private class LinkedListIterator
implements java.util.Iterator<E> {
private Node<E> current = head; // Current index
#Override
public boolean hasNext() {
return (current != null);
}
#Override
public E next() {
E e = current.element;
current = current.next;
return e;
}
#Override
public void remove() {
System.out.println("Implementation left as an exercise");
}
}
private static class Node<E> {
E element;
Node<E> next;
public Node(E element) {
this.element = element;
}
}
}
So I understand to add a previous pointer, I have to do this:
private static class Node<E> {
E element;
Node<E> next;
Node<E> previous;
public Node(E element) {
this.element = element;
}
Now, I am confused - how do I actually implement the necessary methods for the doubly linked list? I am not asking for someone to do the entire assignment, but can someone show me an example of a worked out method?
I also couldn't understand, how does the program know I am referencing the previous element when I do Node<E> previous?
I also dont understand, just because I do "Node previous", how does the program know I am referencing the previous element?
The program doesn't know that you are referencing the previous element. You, the programmer, need to maintain (keep up-to-date and correct) that reference.
Every node will also have a reference to the previous node as it has reference to the next node.
Change the data structure of Node to add an extra Node reference to previous node. So now when someone calls the add(E e) method you will add that element at the tail and set the previous reference of e (which will be the new tail node) to the older tail node (which was the tail before add was called).
So in this way you are managing two references to previous and next nodes.
Also add a new method to your double link list class pervious() and related ones.

Why isn't my java code working? [closed]

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);

Adding an element in an array based Binary Search Tree

So I've stumped on this current problem I'm working on. Basically, I need to add an element to my array based binary search tree. According to my text it is similar to the compareTo method. I'm not even sure what direction to head in. I'm a complete noob when it comes to OOP so any help would be appreciated.
package lab9;
public class BinarySearchTreeArray<E> {
Entry<E> [] tree;
Entry<E> root;
int size;
public BinarySearchTreeArray()
{
tree = null;
size = 0;
}
public int size()
{
return size;
}
public boolean contains(Object obj)
{
Entry<E> temp = root;
int comp;
if (obj == null)
throw new NullPointerException();
while (obj != null)
{
comp = ((Comparable)obj).compareTo (temp.element);
if (comp == 0)
return true;
else if (comp < 0)
temp = temp.left;
else
temp = temp.right;
}//while
return false;
}//contains method
/*
* From the text:
* The definition of the add (E element) method is only a little more
* complicated than the definition of contains (Object obj). Basically,
* the add method starts at the root and branches down the tree
* searching for the element; if the search fails, the element is
* inserted as a leaf.
*/
public void add(E e)
{
Entry<E> node = new Entry<E>(e);
if (tree[parent] == null)
{
tree[0] = node;
size++;
}
else
{
tree[1] = node;
size++;
}
}//add method
/****************************************************************/
protected static class Entry<E>
{
private E element;
private Entry<E> parent, left, right;
public Entry(E e){this.element = element; left = right = null;}
public Entry<E> getLeft(){return left;}
public Entry<E> getRight(){return right;}
}
/****************************************************************/
public static void main(String[] args) {
BinarySearchTreeArray<String> bsta1 = new BinarySearchTreeArray<String>();
BinarySearchTreeArray<Integer> bsta2 = new BinarySearchTreeArray<Integer>();
bsta1.add("dog");
bsta1.add("tutle");
bsta1.add("cat");
bsta1.add("ferrit");
bsta1.add("shark");
bsta1.add("whale");
bsta1.add("porpoise");
bsta2.add(3);
bsta2.add(18);
bsta2.add(4);
bsta2.add(99);
bsta2.add(50);
bsta2.add(23);
bsta2.add(5);
bsta2.add(101);
bsta2.add(77);
bsta2.add(87);
}
}
The add method is indeed similar to your contains method. In a typical binary tree represented with structs/objects you would access the right and left subtrees using pointers (as in your example temp.left and temp.right). But, since you have a tree in an array you need to access that array by index, so the question is : How to access the index that corresponds to the left/right subtrees?
For that, you can use the following expression left = parent * 2 and right = parent * 2 + 1. I will provide you with one example of the add method that would add elements to a tree represented as an array of integers, where -1 represents no values or null in java.
public void add(E e)
{
Entry<E> node = new Entry<E>(e);
index = 0;
int comp;
boolean not_add = true;
while(not_add)
{
if (tree[index] == null) //if this node is empty
{
tree[index] = node;
size++;
not_add = true;
}
comp = ((Comparable)e).compareTo (tree[index].element);
if(comp == 0) not_add = true; // Same value
else if (comp < 0) index = index * 2; // should be insert on the left
else index = index * 2 + 1; // should be insert on the right
}
}

Categories

Resources