DoublyLinkedList Issues traveling backwards - java

I have an assignment to complete a DoublyLinkList assignment and I am having some difficulty with two of the methods. I was given the code for MyList and MyAbstractList and was told to extend MyAbstractList with my DoublyLinkedList. I am not allowed to change MyList or MyAbstractList.
Here is the code for MyList I was provided:
public interface MyList<E extends Comparable<E>> {
/** Return true if this list contains no elements */
public boolean isEmpty();
/** Return the number of elements in this list */
public int size();
/** Add a new element at the proper point */
public void add(E e);
/** Clear the list */
public void clear();
/** Return true if this list contains the element */
public boolean contains(E e);
/** Return the element from this list at the specified index */
public E get(int index);
/** Return the first element in the list */
public E getFirst();
/** Return the last element in the list */
public E getLast();
/** Return the index of the first matching element in this list.
* Return -1 if no match. */
public int indexOf(E e);
/** Return the index of the last matching element in this list
* Return -1 if no match. */
public int lastIndexOf(E e);
/** Remove the first occurrence of the element o from this list.
* Shift any subsequent elements to the left.
* Return true if the element is removed. */
public boolean remove(E e);
/** Remove the element at the specified position in this list
* Shift any subsequent elements to the left.
* Return the element that was removed from the list. */
public boolean remove(int index);
/** Remove the first element in the list, return true if done, false if list is empty */
public boolean removeFirst();
/** Remove the Last element in the list, return true if done, false if list is empty */
public boolean removeLast();
/** Replace the element at the specified position in this list
* with the specified element and return true if done, false if index out of range. */
public boolean set(int index, E e);
}
and this was the code I was provided for MyAbstractList:
public abstract class MyAbstractList<E extends Comparable<E>> implements MyList<E> {
protected int size = 0; // The size of the list
/** Create a default list */
protected MyAbstractList() {
}
/** Create a list from an array of objects */
public MyAbstractList(E[] objects) {
for (int i = 0; i < objects.length; i++)
add(objects[i]);
}
#Override /** Return true if this list contains no elements */
public boolean isEmpty() {
return size == 0;
}
#Override /** Return the number of elements in this list */
public int size() {
return size;
}
}
Finally here is my code for MyDoublyLinkedList:
import java.util.ArrayList;
public class MyDoublyLinkedList<E extends Comparable<E>> extends MyAbstractList<E>
{
int size =0;
Node<E> head = null;
Node<E> current = null;
Node<E> tail = null;
public MyDoublyLinkedList() {
}
/** Create a list from an array of objects */
public MyDoublyLinkedList(E[] objects) {
super(objects);
}
#Override
public boolean isEmpty()
{
return size == 0;
}
#Override
public int size()
{
return size;
}
/** Add a new element at the proper point */
#Override
public void add(E e)
{
Node<E> newNode = new Node<E>(e);
if (tail == null) {
head = tail = newNode;
}
else //if (head != null)
{
tail.next = newNode;
tail = newNode;
}
size++;
}
#Override
public void clear()
{
size = 0;
head = tail = null;
}
#Override
public boolean contains(E e)
{
Node<E> current = head;
for (int i = 0; i < size; i++) {
if (current.element.equals(e))
return true;
current = current.next;
}
return false;
}
#Override
public E get(int index)
{
if (index < 0 || index > size - 1)
return null;
Node<E> current = head;
for (int i = 0; i < index; i++)
current = current.next;
return current.element;
}
#Override
public E getFirst()
{
if (size == 0) {
return null;
}
else {
return head.element;
}
}
#Override
public E getLast()
{
if (size == 0) {
return null;
}
else {
return tail.element;
}
}
#Override
public int indexOf(E e)
{
Node<E> current = head;
for (int i = 0; i < size; i++) {
if (current.element.equals(e))
return i;
current = current.next;
}
return -1;
}
#Override
public int lastIndexOf(E e)
{
int lastIndex = -1;
Node<E> current = head;
for (int i = 0; i < size; i++) {
if (current.element.equals(e))
lastIndex = i;
current = current.next;
}
return lastIndex;
}
/** Remove the first occurrence of the element o from this list.
* Shift any subsequent elements to the left.
* Return true if the element is removed. */
#Override
public boolean remove(E e)
{
int index = indexOf(e);
if (index != -1) {
return remove(index);
} else {
return false;
}
}
/** Remove the element at the specified position in this list
* Shift any subsequent elements to the left.
* Return the element that was removed from the list. */
#Override
public boolean remove(int index)
{
if (index < 0 || index >= size) {
return false;
}
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 true;
}
}
#Override
public boolean removeFirst()
{
if (size == 0) {
return false;
}
else {
Node<E> temp = head;
head = head.next;
size--;
if (head == null) {
tail = null;
}
return true;
}
}
#Override
public boolean removeLast()
{
if (size == 0) {
return false;
}
else if (size == 1) {
Node<E> temp = head;
head = tail = null;
size = 0;
return true;
}
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 true;
}
}
#Override
public boolean set(int index, E e)
{
if (index < 0 || index > size - 1)
return false;
Node<E> current = head;
for (int i = 0; i < index; i++)
current = current.next;
E temp = current.element;
current.element = e;
return true;
}
#Override
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();
}
public String toStringBack()
{
StringBuilder result = new StringBuilder("[");
Node<E> current = tail;
for (int i = 0; i < size; i++) {
result.append(current.element);
current = current.previous;
if (current != null) {
result.append(", "); // Separate two elements with a comma
}
else {
result.append("]"); // Insert the closing ] in the string
}
}
return result.toString();
}
public void add(int index, E e)
{
if (index ==0) {
addFirst(e);// The new node is the only node in list
}
else if(index > size)
{
addLast(e);//The index location was bigger than size
}
else
{
Node<E> current = getAtIndex(index-1);
Node<E> temp = current.next;
current.next = new Node<E>(e);
(current.next).next = temp;
size++;
}
}
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;
}
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++;
}
protected Node<E> getAtIndex(int index)
{
int count;
if (index < 0 || index > size - 1)
return null;
Node<E> temp = null;
if(index <= (size/2))
{
count = -1;
temp = head;
while(++count <= index){
temp = temp.next;
}
}
else if (index > (size/2))
{
count = size;
temp = tail;
while(--count >= index){
temp = temp.previous; //--> this is Where the null pointer exception occurs
}
}
return temp;
}
private static class Node<E>{
E element;
Node<E> next;
Node<E> previous;
public Node(E element){
this.element = element;
next = null;
previous = null;
}
}
}
When I run the add(int index, E e) Method I receive a null pointer exception in the getAtIndext() method. I also have had issues getting the add(E e) Method to add properly when I change the current location. The methods are all as I am being required to use them. The use of iterators while they would be nice are not allowed. I am using Bluj as a compiler. Please let me know what questions you have.
Thank you
EDIT: I do know what a Null Pointer Exception is, I can not figure out why this is coming back as null. The Node "current" should point to the end, then go back in the list until it reaches the indexed location. This only happens when I try to add a node in the last half of the list. The error is thrown at temp = temp.previous;
The stack trace is:
java.lang.NullPointerException at MyDoublyLinkedList.getAtIndex(MyDoublyLinkedList.java:345) at MyDoublyLinkedList.add(MyDoublyLinkedList.java:289) at TestMyDoublyLinkedList.main(TestMyDoublyLinkedList.java:50)
Edit: I figured out the issue. The add() and getAtIndex functions are running properly. When I run the test the function that is throwing a Null Pointer Exception is throwing it at position 8. It cycles through the first few nodes fine, but dies at node 8

When inserting in the add() method, you never assign previous so it is null for all nodes.

Related

How can I fix my code to give the correct output instead of giving nothing?

When i run my code, i get nothing as my output. I suspect my code stops on this method:
public void deleteAt(int position)
{
if (position >= 0)
{
for (int i = position; i < theArray.length; i++)
{
theArray[i] = theArray[i + 1];
}
}
}
I think it stops at the above method because this code:
public int positionOf(char value)
{
//Search the list to find the value, if found return the position, if not, return -1
for (int i = 0; i < size(); i ++)
{
if (theArray[i] == value)
{
return i;
}
}
return -1;
}
only returns -1. If i remove the return -1; then Java thinks that there is an error because there is no return statment. I tried adding an else, but i still get the same error.
This is the whole code:
/** The interface for our List (Abstract Data Type) */
interface IList {
/** Adds the given value to the end of the list */
void append(char value);
/** Adds the given value to the beginning of the list */
void prepend(char value);
/** Deletes the container at the given position (a container holds a value) */
void deleteAt(int position);
/** Returns the number of values currently in our list */
int size();
/** Retrieves the value at the given position */
char getValueAt(int position);
/** Searches for the FIRST occurence of a given value in our list.
* If found, it returns the position of that value.
* If not found, it returns -1 */
int positionOf(char value);
}
/** Array implementation of our List */
class ListAsArray implements IList {
// initialize array to a size of 30 elements
// this will prevent the need to resize our array
char[] theArray = new char[30];
public void append(char value)
{
//Count until you find a place in the array that is empty, then insert
for (int i = 0; i < theArray.length; i ++)
{
if (theArray[i] == 0)
{
theArray[i] = value;
}
}
}
public void prepend(char value)
{
//Count until you find a empty value
for (int i = 0; i < theArray.length; i ++)
{
if (theArray[i] == 0)
{
//Once you find the empty value move everything over
for(int j = theArray.length; j != 0; j--)
{
theArray[i] = theArray[i + 1];
}
}
}
//Finally you want to actually add in the number in the first position
theArray[0] = value;
}
public void deleteAt(int position)
{
if (position >= 0)
{
for (int i = position; i < theArray.length; i++)
{
theArray[i] = theArray[i + 1];
}
}
}
public int size()
{
//Count until you find a place in the array that is empty, then return the number
int count = 0;
for (int i = 0; i < theArray.length; i ++)
{
if (theArray[i] == 0)
{
return count;
}
count ++;
}
return 0;
}
public char getValueAt(int position)
{
return theArray[position];
}
public int positionOf(char value)
{
//Search the list to find the value, if found return the position, if not, return -1
for (int i = 0; i < size(); i ++)
{
if (theArray[i] == value)
{
return i;
}
}
return -1;
}
}
/** Singly Linked List implementation of our List */
class ListAsLinkedList implements IList {
//Point to first node and second node
private Node head;
private Node tail;
//Constructor sets head and tail to null
public void LinkedList()
{
head = null;
tail = null;
}
public void append(char value)
{
//Wrap the data in a node
Node temp = new Node(value);
//Make this the first node if no other nodes
if (tail == null)
{
//Set tail to new node
tail = temp;
//Set head to new node
head = temp;
}
else
{
//Set new node to be after current end
tail.setNext(temp);
//Set as new tail
tail = temp;
}
}
public void prepend(char value)
{
//Wrap the data in a node
Node temp = new Node(value);
//Make this the first node if no other nodes
if (tail == null)
{
//Set tail to new node
tail = temp;
//Set head to new node
head = temp;
}
else
{
temp.next = head;
head = temp;
}
}
public void deleteAt(int position)
{
//Make the head node the next node if its the first one
if(position == 0)
{
head=head.next;
}
//If that wasn't the case...
Node current = head;
for(int i = 0; i < position-1; i++)
{
current = current.next;
}
current.next = current.next.next;
if(current.getNext() == null)
{
tail = current;
}
}
public int size()
{
Node temp = head;
for (int i = 0; i != 103; i++)
{
if (temp == tail)
{
return i;
}
}
return 0;
}
public char getValueAt(int position)
{
Node temp=head;
for(int i=0; i < position; i++)
{
temp=temp.next;
}
return temp.data;
}
public int positionOf(char value)
{
//Start at the beginning
int position = 0;
Node current = head;
//Look until we find target data
while (current.getData() != value)
{
//Move to next node
current = current.getNext();
//Increment position
position++;
}
//return position found
return position;
}
}
/** A singly linked list node for our singly linked list */
class Node {
//The node data and link to next node
public char data;
public Node next;
//Constructor
public Node(char data)
{
this.data = data;
this.next = null;
}
//Accessor
public char getData()
{
return data;
}
//Accessor
public Node getNext()
{
return next;
}
//Mutator
public void setData(char data)
{
this.data = data;
}
//Mutator
public void setNext(Node next)
{
this.next = next;
}
}
This is main:
/** contains our entry point */
public class Main {
/** entry point - DO NOT CHANGE the pre-existing code below */
public static void main(String[] args) {
int[] numbers = {105,116,112,115,65,58,47,47,116,105,110,121,88,117,114,108,46,99,111,109,47};
int[] numbers2 = {97,59,111,53,33,111,106,42,50};
int[] numbers3 = {116,104,32,111,116,32,111,71};
/// List as an Array
IList array = new ListAsArray();
// add values
for(int num : numbers) {
array.append((char)num);
}
for(int num : numbers3) {
array.prepend((char)num);
}
// delete some values
int position;
position = array.positionOf((char)105);
array.deleteAt(position);
position = array.positionOf((char)65);
array.deleteAt(position);
position = array.positionOf((char)88);
array.deleteAt(position);
// print em
position = 0;
while (position < array.size()) {
System.out.print(array.getValueAt(position));
position++;
}
/// List as a Linked List
IList linkedList = new ListAsLinkedList();
// add values
for(int num : numbers2) {
linkedList.append((char)num);
}
linkedList.prepend((char)55);
linkedList.prepend((char)121);
// delete some values
position = linkedList.positionOf((char)59);
linkedList.deleteAt(position);
position = linkedList.positionOf((char)33);
linkedList.deleteAt(position);
position = linkedList.positionOf((char)42);
linkedList.deleteAt(position);
// print em
position = 0;
while (position < linkedList.size()) {
System.out.print(linkedList.getValueAt(position));
position++;
}
System.out.println();
// ???
}
}
It should be outputting a link pertaining to the next part of my assignment.
The size() method always returns 0 according to your input.
size() method as per your code doesn't give you the length of the array to iterate over. Therefore you should use array length i.e theArray.length in positionOf() method's for loop instead of size() method.

How to write an add/insert method with a DoublyLinkedList in Java

I need help with my add method in java. It works with DoublyLinked List.
I am implementing a cyclic DoublyLinkedList data structure. Like a singly
linked list, nodes in a doubly linked list have a reference to the next node, but unlike a singly linked list, nodes in a doubly linked list also have a reference to the previous node. Additionally, because the list is "cyclic", the "next" reference in the last node in the list points to the first node in the list, and the "prev" reference in the first node in the list points to the last node in the list.
What the method is suppose to do is insert the value parameter at the specified index in the list. Be sure to address the case in which the list
is empty and/or the added element is the first in the list. If the index parameter is invalid, an IndexOutOfBoundsException should be thrown.
Here is my code below:
public class DoublyLinkedList<E>
{
private Node first;
private int size;
#SuppressWarnings("unchecked")
public void add(E value)
{
if (first == null)
{
first = new Node(value, null, null);
first.next = first;
first.prev = first;
}
else
{
first.prev.next = new Node(value, first, first.prev);
first.prev = first.prev.next;
}
size++;
}
private class Node<E>
{
private E data;
private Node next;
private Node prev;
public Node(E data, Node next, Node prev)
{
this.data = data;
this.next = next;
this.prev = prev;
}
}
Here is the method where it fails. I will comment the line where I'm stuck on, but other than that, what is done in the previous lines is correct from what I heard.
#SuppressWarnings("unchecked")
public void add(int index, E value)
{
if(index < 0)
{
throw new IndexOutOfBoundsException();
}
if(index > size)
{
throw new IndexOutOfBoundsException();
}
if (first.data == null)
{
throw new NullPointerException();
}
if (index == 0)
{
first = new Node(value, null, null);
first.next = first;
first.prev = first;
}
else
{
Node current = first;
for (int i = 0; i < index; i++)
{
current = current.next;
}
current.prev.next = new Node(value, current, current.prev); // This is the line where I get lost on.
current.prev = current.prev.next;
}
size++;
}
The rest of my code is here. Please focus on the method I'm working on. thank you!
#SuppressWarnings("unchecked")
public void remove(int index)
{
if(index < 0)
{
throw new IndexOutOfBoundsException();
}
if(index > size)
{
throw new IndexOutOfBoundsException();
}
if (first.data == null)
{
throw new IndexOutOfBoundsException();
}
else if (index == 0)
{
first = first.next;
}
else
{
Node current = first.next;
for (int i = 0; i < index; i++)
{
current = current.next;
}
// current.prev = current.next;
current.next = current.next.next;
}
size--;
}
#SuppressWarnings("unchecked")
public E get(int index)
{
if(index < 0)
{
throw new IndexOutOfBoundsException();
}
if(index > size)
{
throw new IndexOutOfBoundsException();
}
Node current = first;
for (int i = 0; i < index; i++)
{
current = current.next;
}
return (E) current.data;
}
#SuppressWarnings("unchecked")
public int indexOf(E value)
{
int index = 0;
Node current = first;
while (current != current.next)
{
if (current.data.equals(value))
{
return index;
}
index++;
current = current.next;
}
return index;
}
public boolean isEmpty()
{
if (size == 0)
{
return true;
}
else
{
return false;
}
}
public int size()
{
return size;
}
#SuppressWarnings("unchecked")
public String toString()
{
if (isEmpty())
{
return "[]";
}
else
{
String result = "[" + first.data;
Node current = first.next;
for(int i = 0; i < size-1; i++)
{
result += ", " + current.data;
current = current.next;
}
result += "]";
return result;
}
}
}
This was not easy at all, however I figured out the answer to my question.
#SuppressWarnings("unchecked")
public void add(int index, E value)
{
if(index > size || index < 0)
{
throw new IndexOutOfBoundsException();
}
if (first == null)
{
Node n = new Node(value, null, null);
n.next = n;
n.prev = n;
first = n;
}
else
{
Node current = first;
for (int i = 0; i < index; i++)
{
current = current.next;
}
//current points to node that will follow new node.
Node n2 = new Node(value, current, current.prev);
current.prev.next = n2;
current.prev = n2;
//update first if necessary.
if(index == 0)
{
first = n2;
}
}
size++;
}

Copy a single Linked list with parameter (Node <E> node)

The problem I am facing is figuring out how to write a method
public SingleLinkedList copy(Node <E> node) {
}
To return a copy of the list. I have tried:
public SingleLinkedList copy(Node <E> node) {
SingleLinkedList<E> temp = new SingleLinkedList<E>();
Node<E> ref = head;
for(Node<E> n = ref ;ref!= null; n = n.next){
temp.add(n, ref.data);
ref = ref.next;
}
return temp;
}
I created a new list called temp, changed head to ref, iterate through the list and add it to the new list and return the new list, but there's an error with temp.add(n, ref.data).
What am I possibly doing wrong?
class SingleLinkedList<E> {
private static class Node<E> {
private E data;//removed final * private final E data
private Node<E> next;
private Node(E item) {
data = item;
}
}
private Node<E> head;
private int size;
/* Insert item at index, returns true if add is successful. */
public boolean add(int index, E item) {
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException("" + index);
}
if (index == 0) { // adding to the front
Node<E> t = head;
head = new Node<>(item);
head.next = t;
} else { // adding anywhere other than front
Node<E> left = getNode(index - 1);
Node<E> node = new Node(item);
Node<E> right = left.next;
left.next = node;
node.next = right;
}
size++;
return true;
}
/* Add item at end of list, returns true if successful. */
public boolean add(E item) {
return add(size, item);
}
/* Return item at index */
public E get(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("" + index);
}
return getNode(index).data;
}
/* Return the number of items */
public int size() {
return size;
}
/* Returns a string representation of the list */
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[ ");
for (Node<E> n = head; n != null; n = n.next) {
sb.append(n.data);
sb.append(" ");
}
sb.append("]");
return sb.toString();
}
/* Return the node at location index */
private Node<E> getNode(int index) {
Node<E> n = head;
for (int i = 0; i < index; i++)
n = n.next;
return n;
}
The problem is you need to pass the position as an int. I also removed the Node n because you do not need it anyways.
I think this should work.
public SingleLinkedList copy() {
SingleLinkedList<E> temp = new SingleLinkedList<E>();
int i = 0;
for(Node<E> ref = head ;ref!= null; ref = ref.next){
temp.add(i++, ref.data);
}
return temp;
}
EDIT: I forgot to drop the parameter you do not need it at all.

Circular Doubly LinkedList ListIterator

This is a homework question. I have a Double Linked Node class, Circular Double Linked List class which implements Iterable, and a Iterator class that implements Iterator. I understand the concept of an iterator where an implicit cursor sits between two nodes and on a call to next() it returns the node it just jumped over. I created a test class with a new list object. I then created an iterator and called next, I received the correct No Such Element exception but when I added some nodes to the list I received a Null Pointer Exception instead of it returning the last returned node. How can I correct this?
My Node class:
public class DoubleLinkedNode<E>{
private E data;
private DoubleLinkedNode<E> next;
private DoubleLinkedNode<E> prev;
public DoubleLinkedNode(E data, DoubleLinkedNode<E> next, DoubleLinkedNode<E> prev){
this.data = data;
this.next = next;
this.prev = prev;
}
/**
* Used to construct a node that points to null for its prev and next.
* #param data Data is a generic variable to be stored in the node.
*/
public DoubleLinkedNode(E data){
this(data, null, null);
}
//getters
public E getData(){
return data;
}
public DoubleLinkedNode<E> getNext(){
return next;
}
public DoubleLinkedNode<E> getPrev(){
return prev;
}
//setters
public void setData(E data){
this.data = data;
}
public void setNext(DoubleLinkedNode<E> next){
this.next = next;
}
public void setPrev(DoubleLinkedNode<E> prev){
this.prev = prev;
}
#Override public String toString(){
if(data == null){
return null;
}
else{
return data.toString();
}
}
}
The List class with the private inner Iterator class:
import java.util.Iterator;
import java.util.ListIterator;
import java.util.NoSuchElementException;
public class CircularDoubleLinkedList<E> implements Iterable<E>{
private int size;
private DoubleLinkedNode<E> head;
public CircularDoubleLinkedList(){
this.head = null;
this.size = 0;
}
/**
* Adds an item to the end of the list.
*
* #param data The Data that is to be stored in the node.
*/
public void add(E data){
DoubleLinkedNode<E> newNode = new DoubleLinkedNode<E>(data);
if(this.head == null){
newNode.setNext(newNode);
newNode.setPrev(newNode);
this.head = newNode;
this.size++;
//if list is empty create a new node and insert
}
else{
DoubleLinkedNode<E> temp = this.head.getPrev();
this.head.getPrev().setNext(newNode);
this.head.setPrev(newNode);
newNode.setPrev(temp);
newNode.setNext(this.head);
this.size++;
}
}
/**
* Which adds an item at the specified index.
*
* #param index The index in which the new Node is added.
* #param data The data which is to be stored in the node.
*/
public void add(int index, E data){
int currIndex = 0;
DoubleLinkedNode<E> currNode = this.head;
DoubleLinkedNode<E> nextNode = this.head.getNext();
DoubleLinkedNode<E> prevNode = this.head.getPrev();
DoubleLinkedNode<E> newNode = new DoubleLinkedNode<E>(data);
if(index == 0){
prevNode.setNext(newNode);
currNode.setPrev(newNode);
newNode.setPrev(prevNode);
newNode.setNext(currNode);
this.head = newNode;
this.size++;
}
else if (index > 0){
while(currIndex != this.size){
if(currIndex != index%size){
currIndex++;
currNode = currNode.getNext();
nextNode = nextNode.getNext();
prevNode = prevNode.getNext();
}else{
newNode.setPrev(prevNode);
newNode.setNext(currNode);
prevNode.setNext(newNode);
currNode.setPrev(newNode);
currNode = newNode;
this.size++;
break;
}
}
}
else if (index < 0){
while(currIndex != -this.size){
if(currIndex != index%size){
currIndex--;
currNode = currNode.getPrev();
prevNode = prevNode.getPrev();
nextNode = nextNode.getPrev();
}else{
newNode.setNext(nextNode);
newNode.setPrev(currNode);
currNode.setNext(newNode);
nextNode.setPrev(newNode);
currNode = newNode;
this.size++;
break;
}
}
}
}
/**
* Returns the data stored at the specified index.
*
* #param index The index determines the node whose data is returned.
* #return Returns the data of the node at the index.
*/
public E get(int index){//returns the data stored at the specified index
int currIndex = 0;
DoubleLinkedNode<E> currNode = this.head;
E temp = null;
if(index == 0){//zero case
temp = currNode.getData();
}
else if(index > 0){//positive
while(currIndex != this.size){
if(currIndex != index%size){
currIndex++;
currNode = currNode.getNext();
}else{
temp = currNode.getData();
break;
}
}
}
else if(index < 0){//negative
while(currIndex != -this.size){
if(currIndex != index%size){
currIndex--;
currNode = currNode.getPrev();
}else{
temp = currNode.getData();
break;
}
}
}
return temp;
}
/**
* Which removes and returns an item from the list.
*
* #param index Removes the node at the current index.
* #return Returns the data of the removed node.
*/
public E remove(int index){//which removes and returns an item from the list
int currIndex = 0;
DoubleLinkedNode<E> currNode = this.head;
DoubleLinkedNode<E> nextNode = this.head.getNext();
DoubleLinkedNode<E> prevNode = this.head.getPrev();
E temp = null;
if(index == 0){
temp = currNode.getData();
prevNode.setNext(currNode.getNext());
nextNode.setPrev(currNode.getPrev());
this.head = nextNode;
size--;
}
else if(index > 0){//positive
while(currIndex != this.size){
if(currIndex != index%size){
currIndex++;
currNode = currNode.getNext();
nextNode = nextNode.getNext();
prevNode = prevNode.getNext();
}else{
temp = currNode.getData();
prevNode.setNext(currNode.getNext());
nextNode.setPrev(currNode.getPrev());
currNode = nextNode;
size--;
break;
}
}
}
else if(index < 0){//negative
while(currIndex != -this.size){
if(currIndex != index%size){
currIndex--;
currNode = currNode.getPrev();
prevNode = prevNode.getPrev();
nextNode = nextNode.getPrev();
}else{
temp = currNode.getData();
prevNode.setNext(currNode.getNext());
nextNode.setPrev(currNode.getPrev());
currNode = prevNode;
size--;
break;
}
}
}
return temp;
}
/**
* Returns the size.
*
* #return
*/
public int size(){
return size;
}
#Override public String toString(){
String str = "[";
int index = 0;
DoubleLinkedNode<E> curr = head;
if(size == 0){
return "There is no one here to kill.";
}else{
while (index <this.size) {
str += curr.getData();
curr = curr.getNext();
index++;
if (index<this.size) {
str += ", ";
}
}
str += "]";
}
return str;
}
#Override
public Iterator<E> iterator() {
return new CircularDoubleIterator();
}
// Iterator inner class begins
private class CircularDoubleIterator implements ListIterator<E> {
private DoubleLinkedNode<E> nextItem;//reference to next item
private int index = 0;
private DoubleLinkedNode<E> lastReturned;// the last node to be returned by prev() or next()
// reset to null after a remove() or add()
#Override
public E next() {
if(!hasNext()){
throw new NoSuchElementException("No such element.");
}
else{
nextItem = head; //edited 11Sept13
lastReturned = nextItem.getNext();
nextItem = nextItem.getNext();
head = nextItem; //edited 11Sept13
index++;
return lastReturned.getData();
}
}
#Override
public E previous() {
if(!hasPrevious()){
throw new NoSuchElementException("No such element.");
}
else{
index--;
return ;
}
}
#Override
public int nextIndex() {
return index;
}
#Override
public int previousIndex() {
return index-1;
}
#Override
public boolean hasNext() {
return size != 0;
}
#Override
public boolean hasPrevious() {
return size!= 0;
}
#Override
public void remove() {
}
#Override
public void set(E theData) {
if(lastReturned == null){
throw new IllegalStateException();
}
else{
}
}
#Override
public void add(E theData) {
if(size == 0){
}
else if(size != 0){
}
}
}
//Iterator inner class ends
}
I don't see where you assign values to private DoubleLinkedNode<E> nextItem; when you create iterator.
I cannot see the whole code. So I assume that nextItem is null or its next field is null.

deleteBack java program

I am doing some exercises on practice-it website. And there is a problem that I don't understand why I didn't pass
Write a method deleteBack that deletes the last value (the value at the back of the list) and returns the deleted value. If the list is empty, your method should throw a NoSuchElementException.
Assume that you are adding this method to the LinkedIntList class as defined below:
// A LinkedIntList object can be used to store a list of integers.
public class LinkedIntList {
private ListNode front; // node holding first value in list (null if empty)
private String name = "front"; // string to print for front of list
// Constructs an empty list.
public LinkedIntList() {
front = null;
}
// Constructs a list containing the given elements.
// For quick initialization via Practice-It test cases.
public LinkedIntList(int... elements) {
this("front", elements);
}
public LinkedIntList(String name, int... elements) {
this.name = name;
if (elements.length > 0) {
front = new ListNode(elements[0]);
ListNode current = front;
for (int i = 1; i < elements.length; i++) {
current.next = new ListNode(elements[i]);
current = current.next;
}
}
}
// Constructs a list containing the given front node.
// For quick initialization via Practice-It ListNode test cases.
private LinkedIntList(String name, ListNode front) {
this.name = name;
this.front = front;
}
// Appends the given value to the end of the list.
public void add(int value) {
if (front == null) {
front = new ListNode(value, front);
} else {
ListNode current = front;
while (current.next != null) {
current = current.next;
}
current.next = new ListNode(value);
}
}
// Inserts the given value at the given index in the list.
// Precondition: 0 <= index <= size
public void add(int index, int value) {
if (index == 0) {
front = new ListNode(value, front);
} else {
ListNode current = front;
for (int i = 0; i < index - 1; i++) {
current = current.next;
}
current.next = new ListNode(value, current.next);
}
}
public boolean equals(Object o) {
if (o instanceof LinkedIntList) {
LinkedIntList other = (LinkedIntList) o;
return toString().equals(other.toString()); // hackish
} else {
return false;
}
}
// Returns the integer at the given index in the list.
// Precondition: 0 <= index < size
public int get(int index) {
ListNode current = front;
for (int i = 0; i < index; i++) {
current = current.next;
}
return current.data;
}
// Removes the value at the given index from the list.
// Precondition: 0 <= index < size
public void remove(int index) {
if (index == 0) {
front = front.next;
} else {
ListNode current = front;
for (int i = 0; i < index - 1; i++) {
current = current.next;
}
current.next = current.next.next;
}
}
// Returns the number of elements in the list.
public int size() {
int count = 0;
ListNode current = front;
while (current != null) {
count++;
current = current.next;
}
return count;
}
// Returns a text representation of the list, giving
// indications as to the nodes and link structure of the list.
// Detects student bugs where the student has inserted a cycle
// into the list.
public String toFormattedString() {
ListNode.clearCycleData();
String result = this.name;
ListNode current = front;
boolean cycle = false;
while (current != null) {
result += " -> [" + current.data + "]";
if (current.cycle) {
result += " (cycle!)";
cycle = true;
break;
}
current = current.__gotoNext();
}
if (!cycle) {
result += " /";
}
return result;
}
// Returns a text representation of the list.
public String toString() {
return toFormattedString();
}
// ListNode is a class for storing a single node of a linked list. This
// node class is for a list of integer values.
// Most of the icky code is related to the task of figuring out
// if the student has accidentally created a cycle by pointing a later part of the list back to an earlier part.
public static class ListNode {
private static final List<ListNode> ALL_NODES = new ArrayList<ListNode>();
public static void clearCycleData() {
for (ListNode node : ALL_NODES) {
node.visited = false;
node.cycle = false;
}
}
public int data; // data stored in this node
public ListNode next; // link to next node in the list
public boolean visited; // has this node been seen yet?
public boolean cycle; // is there a cycle at this node?
// post: constructs a node with data 0 and null link
public ListNode() {
this(0, null);
}
// post: constructs a node with given data and null link
public ListNode(int data) {
this(data, null);
}
// post: constructs a node with given data and given link
public ListNode(int data, ListNode next) {
ALL_NODES.add(this);
this.data = data;
this.next = next;
this.visited = false;
this.cycle = false;
}
public ListNode __gotoNext() {
return __gotoNext(true);
}
public ListNode __gotoNext(boolean checkForCycle) {
if (checkForCycle) {
visited = true;
if (next != null) {
if (next.visited) {
// throw new IllegalStateException("cycle detected in list");
next.cycle = true;
}
next.visited = true;
}
}
return next;
}
}
// YOUR CODE GOES HERE
}
My work so far is this:
public int deleteBack(){
if(front==null){
throw new NoSuchElementException();
}else{
ListNode current = front;
while(current!=null){
current = current.next;
}
int i = current.data;
current = null;
return i;
}
}
Don't you want to iterate until the current.next is != null?
What you have now passes the entire list, and your last statements do nothing, since current is null already.
Think about the logic you have here
while(current!=null){
current = current.next;
}
When that loop exits, current == null, and then you try to access current's data. Does this point you in the right direction?
// This is the quick and dirty
//By Shewan
public int deleteBack(){
if(size()== 0){ throw new NoSuchElementException(); }
if(front==null){ throw new NoSuchElementException();
}else{
if(front.next == null){
int i = front.data;
front = null;
return i;
}
ListNode current = front.next;
ListNode prev= front;
while(current.next!=null){
prev = current;
current = current.next;
}
int i = current.data;
prev.next = null;
return i;
}
}

Categories