Iterable Deque NullPointerException - java

I am attempting to create an Deque class (Stack/Queue that can be added to and referenced at both ends) by implementing a doubly linked-list format.
import java.util.Iterator;
public class Deque implements Iterable {
Node first;
Node last;
int size;
public Deque()
{
first = null;
last = null;
size = 2;
first.next = last;
last.prev = first;
}
private class Node
{
Node next;
Node prev;
Item item;
}
private class ListIterator implements Iterator<Item>
{
private Node current = first;
public boolean hasNext()
{
return current.next != null;
}
public Item next()
{
Item item = current.item;
current = current.next;
return item;
}
public void remove()
{
/* not supported */
}
}
public boolean isEmpty()
{
if(first == null&&last == null)
return true;
return false;
}
public int size()
{
return size;
}
public void addFirst(Item item)
{
Node oldfirst = first;
first = new Node();
first.item = item;
first.next = oldfirst;
oldfirst.prev = first;
size++;
}
public void addLast(Item item)
{
Node oldlast = last;
last = new Node();
last.item = item;
last.prev = oldlast;
oldlast.next = last;
size++;
}
public Item removeFirst()
{
Item item = first.item;
first = first.next;
size--;
return item;
}
public Item removeLast()
{
Item item = last.item;
last = last.next;
size--;
return item;
}
#Override
public Iterator<Item> iterator()
{
return (new ListIterator());
}
public static void main(String[] args)
{
Deque<Integer> deque = new Deque<Integer>();
for(int i=0; i<5; i++)
{
deque.addFirst(i);
deque.addLast(9-i);
}
for(Integer i : deque)
{
StdOut.println(i);
}
}
}
When I run the code, I get a NullPointerException when it tries to do first.next = last; I can understand why, but I'm not sure how to fix it without breaking the list. Any solutions? Is it perhaps unnecessary to use a doubly linked format (i.e. remove the prev reference Node altogether)?

You avoid NullPointerException by avoiding access to uninitialized variables.
In that particular example, leave out the:
first.next = last;
last.prev = first;
in your constructor and use defensive programming and check for null if it could be uninitialized, before accessing a variable.
For example in your addFirst method:
public void addFirst(Item item)
{
Node oldfirst;
if (first != null){
oldfirst = first;
}
first = new Node();
first.item = item;
if (oldfirst != null){
first.next = oldfirst;
oldfirst.prev = first;
}
size++;
}
etc.
By the way, is this a learning exercise? If not, Java library does have Deques ready to use, including linked list:
http://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html

How is your size beginning at 2? It should be 0 until you add an Item.
You initial conditions should be that both prev and next are null. When you add a single item, then size should be 1 and both prev and next should point to that object.

When the Deque is empty, there is no "next" and "previous". It is completely empty. There would be "next" and "previous" only as soon as there is data.
So when you initialize the Deque, you should not attempt to assign a prev and next to null references. The fact that they are null indicates that there's nothing there, so of course there is nothing that comes previously or after it.
And of course, the size should be zero.
Then, in your addFirst and addLast methods, you should handle the case in which your first and last are null. In that case, you have to initialize them both to the same value, where its next and prev are both null. And set the size to 1.
Only proceed as you did (add item, correct the linkage) if the item in first or last respectively is not null.
And remember to check for null in your removeFirst and removeLast methods as well.
Short version: the case of an empty list is special. You should start with an empty list. You should check for this special case in your add and remove methods.

Related

How can I remove the last node of a Linked List in java?

I need to implement two methods removeFirst and removeLast of a LinkedList in Java
The first method i solved it like this:
#Override
public E removeFirst() {
if(isEmpty()){
throw new NoSuchElementException();
}
E element = top.next.data;
top.next = top.next.next;
numElements--;
return element;
}
I'm having problems with removeLast method
public E removeLast() {
if(isEmpty()){
throw new NoSuchElementException();
}
for (int i = 0; i < numElements;i++) {
}
}
My idea is using a for cycle to look for the last element, but i don't know what to do after that
Any suggestions?
My Node class is the following:
public class Node<E> {
E data;
Node<E> next;
public Node(E data) {
this(data,null);
}
public Node(E data, Node<E> next) {
this.data = data;
this.next = null;
}
#Override
public String toString () {
return data.toString();
}
}
We have to keep two pointers previous and current. Since we are keeping a record for the number of elements in the list we can use for loop to traversal the list and find the last node pointed by currentNode pointer and previous node pointed by previousNode pointer. At last, update the previous next pointer to null and return currentNode data.
public E removeLast() {
if(isEmpty()){
throw new NoSuchElementException();
}
Node previousNode = top;
Node currentNode = top;
for (int i = 0; i < numElements -1 ;i++) {
previousNode = currentNode;
currentNode = currentNode.next;
}
// removed the last element and return the data
previousNode.next = null;
numElements--
return currentNode.data;
}
removeFirst and removeLast already exist in the LinkedList class (LinkedList javadoc). No need to create them from scratch then.
Something like this may work, it's hard to say without seeing your list class because I can't test it:
public E removeLast() {
if(isEmpty()){
throw new NoSuchElementException();
}
Node<E> node = top;
while (true) {
Node<E> nextNode = node.next;
if (nextNode.next == null) {
node.next = null;
return nextNode.data;
} else {
node = nextNode;
}
}
}
But it's worth adding that usually in a singly linked list, you want the containing class to keep a tail pointer (otherwise you can't append to the end efficiently). If you do this, you will need to update your tail as well.
And another comment, if you do find yourself removing the last on a regular basis, you want to switch to a doubly linked list...and why aren't you just using the builtin java.util.LinkedList class? Is this for a school project or something?
This logic shall work -
Node <E> tmp;
tmp = next;
while(tmp.next.next != null)
tmp = tmp.next;
tmp.setNext(null);
So if we have 1->3->4->null
Whenever it gets to 3 it shall setNext to null
so the new array will look like this 1->3->null
public node removelast() {
if(isEmpty())
return null;
node temp =head;
node temp2 =head.getNext();
while(temp!=null && temp2!=null) {
if(temp2.getNext()==null) {
tail=temp;
temp.setNext(null);
}
temp2=temp2.getNext();
temp=temp.getNext();
}
if(head.getNext()==null)
tail=head;
return tail;
}

Why does my iterator foreach loop never enter/execute?

I have a for-each loop in a method toString() that should iterate through elements in a generic FIFO queue (implemented using doubly linked list data structure) and concatenate the items in the queue onto the string a, which is returned to enqueue() which prints the string, which is a representation of my queue and its contents after an enqueue call. MY question is, why is the for-each not being executed/entered at all?
I tried inserting System.out.print("Hi"); inside the for-each, and it did not print. So I assume some block(s) of code is hindering it from executing properly.
// FIFOQueue is implemented using the structure double linked list (DLL)
// Generic, iterable
import java.util.Iterator;
import java.util.*;
public class FIFOQueueDLL<Item> implements Iterable<Item>{
private Node first;
private Node last;
private int length = 0;
// is the queue empty?
public boolean isEmpty(){
return length == 0;
}
private class Node{
Item item;
Node next;
Node previous;
}
// add an item
public void enqueue(Item n){
Node newnode = new Node();
newnode.item = n;
if(isEmpty()){
last = newnode;
} else {
first.previous = newnode;
}
newnode.next = first;
first = newnode;
length++;
System.out.println(this);
}
// remove and return the least recently added item
public Item dequeue(){
if(isEmpty()){
throw new NoSuchElementException();
}
Node t = last;
if(first == last){
first = null;
} else {
last.previous.next = null;
}
last = last.previous;
t.previous = null;
length--;
System.out.println(this.toString(););
return t.item;
}
public String toString(){
String a = "123";
for(Item item : this){
a = a + item;
}
return a;
}
public Iterator<Item> iterator(){
return new FIFOIterator();
}
private class FIFOIterator implements Iterator<Item>{
// Declare attribute
Node curr;
// Set attribute of node curr
public FIFOIterator(){
Node curr = first;
curr.item = first.item;
curr.next = first.next;
}
//private int i = length;
public boolean hasNext(){
return curr != null;
}
public Item next(){
Item a = curr.item;
curr = curr.next;
return a;
}
}
public static void main(String[] args){
FIFOQueueDLL<Character> c = new FIFOQueueDLL<Character>();
char b = 'b';
c.enqueue(b);
c.enqueue(b);
}
}
Expected output: 123b
123bb
Actual output: 123
123
Your FIFOIterator constructor creates a new object curr but does not set it to the field of the same class. Thus your field curr is null and hasNext returns false.
Change
// Set attribute of node curr
public FIFOIterator(){
Node curr = first;
curr.item = first.item;
curr.next = first.next;
}
to
// Set attribute of node curr
public FIFOIterator(){
this.curr = first;
}
I debugged this codeblock:
public String toString(){
String a = "123";
for(Item item : this){
a = a + item;
}
return a;
}
and saw that "this" holds the value of the String a. Do you want to change Item class to Character class instead, and call toCharArray() method on a instead of using this. This is what I am talking about:
public String toString(){
String a = "123";
for(Character item : a.toCharArray()){
a = a + item;
}
return a;
}
you will get into the loop and be able to append any new character you want. Hope this helps.

Will my Circular LinkedList work correctly?

So I am currently trying to create a circle linked list (double linked list with each value having a previous, and a next value not equal to null), and I am not sure if I am properly creating it. My goal is to be able to create a LinkedList of values, and then when I iterate through the list, hasNext() should always return true (no null values). I think there is something wrong with the way I am adding values, but I am not sure. Here is the code, with the CircularList class having an inner node class:
public class CircularList<E> {
//I decided to still have heads and tails, to link them together
private Node<E> first = null;
private Node<E> last = null;
private Node<E> temp;
private int size;
//inner node class
private static class Node<E>{ //In this case I am using String nodes
private E data; //matching the example in the book, this is the data of the node
private Node<E> next; //next value
private Node<E> prev; //previous value
//Node constructors, also since in this case this is a circular linked list there should be no null values for previous and next
private Node(E data, Node<E> next, Node<E> prev){
this.data = data;
this.next = next;
this.prev = prev;
}
}
//end of inner node class
public void addValue(E item){
Node<E> n = new Node<E>(item, first, last);
if(emptyList() == true){ //if the list is empty
//only one value in the list
first = n;
last = n;
}
else{ //if the list has at least one value already
temp = first;
first = n;
first.next = temp;
last.next = first;
}
size++;
}
public boolean emptyList(){
boolean result = false;
if(first == null && last == null){ //if there is no values at all
result = true;
}
return result;
}
}
Just did a quick scan but this is the bit where it goes wrong:
Node<E> n = new Node<E>(item, first, last);
if(emptyList() == true) {
//if the list is empty
//only one value in the list
first = n;
last = n;
}
The prev and next item inside node are still null here. You should set those too.
else {
//if the list has at least one value already
temp = first;
first = n;
first.next = temp;
last.next = first;
}
Additionally you're not updating prev here.
Also consider using a linked list internally as a backing data structure rather then your own node structure. Then you only have to create the circular iterator.

Add node to end of Linked List

Having a bit of trouble adding a node to the end of my linked list. It only seems to display the very last one I added before I call my addFirst method. To me it looks like on the addLast method I'm trying to first create the node to assign it 5, then for the following numbers use a while loop to assign them to the last node on the linked list. Little stuck on why I can't get my output to display 5 and 6.
class LinkedList
{
private class Node
{
private Node link;
private int x;
}
//----------------------------------
private Node first = null;
//----------------------------------
public void addFirst(int d)
{
Node newNode = new Node();
newNode.x = d;
newNode.link = first;
first = newNode;
}
//----------------------------------
public void addLast(int d)
{
first = new Node();
if (first == null)
{
first = first.link;
}
Node newLast = new Node();
while (first.link != null)
{
first = first.link;
}
newLast.x = d;
first.link = newLast;
first = newLast;
}
//----------------------------------
public void traverse()
{
Node p = first;
while (p != null)
{
System.out.println(p.x);
p = p.link;
}
}
}
//==============================================
class test123
{
public static void main(String[] args)
{
LinkedList list = new LinkedList();
list.addLast(5);
list.addLast(6);
list.addLast(7);
list.addFirst(1);
list.addFirst(2);
list.addFirst(3);
System.out.println("Numbers on list");
list.traverse();
}
}
I've also tried creating a last Node and in the traverse method using a separate loop to traverse the last node. I end up with the same output!
public void addLast(int d)
{
Node newLast = new Node();
while (last.link != null)
{
last = newLast.link;
}
newLast.x = d;
newLast.link = last;
last = newLast;
}
The logic of your addLast method was wrong. Your method was reassigning first with every call the logic falls apart from that point forward. This method will create the Node for last and if the list is empty simply assign first to the new node last. If first is not null it will traverse the list until it finds a Node with a null link and make the assignment for that Nodes link.
public void addLast(int d) {
Node last = new Node();
last.x = d;
Node node = first;
if (first == null) {
first = last;
} else {
while (node.link != null) {
node = node.link;
}
node.link = last;
}
}
Your addLast() method displays the value of the last node because every time you append a node to the end of your list, you are overwriting the reference to "first". You are also doing this when you assign a new reference to first in the following line:
first = new Node();
Try the following:
public void addLast(int d)
{
Node newLast = new Node();
if (first == null)
{
newLast.x = d;
first = newLast;
return;
}
Node curr = first;
while (curr.link != null)
{
curr = curr.link;
}
newLast.x = d;
curr.link = newLast;
}
The method creates a new node and it is added to the end of the list after checking two conditions:
1.) If first is null: in this case the list is empty and the first node should be
initialized to the new node you are creating, then it will return (or you could do
an if-else).
2.) If first is not null: If the list is not empty you'll loop through your list until you
end up with a reference to the last node, after which you will set its next node to the
one you just created.
If you wanted to keep track of the tail of your list called "last", like you mentioned above, then add:
last = newLast
at the end of your method. Hope this helps!

attempting to convert a linked list to a circular linked list

I been working on this assignment for a long time. I finally got the tester to print the content in the list and the methods working, but now I need to connect the elements on the list forming a circle and keep them this way when removing or adding elements. My book doesn't cover anything regarding circular linked list and I attempted to apply the concept of a few samples I seen in here for circular linked list without any success.
I would greatly appreciative any help.
Here is what I have:
import java.util.NoSuchElementException;
/**
A circular linked list.
*/
public class LinkedList
{
private Node last;
// Don't add other instance fields
/**
Constructs an empty linked list.
*/
public LinkedList()
{
last = null;
}
/**
Returns the first element in the linked list.
#return the first element in the linked list
*/
public Object getFirst()
{
//. . .
if (last == null)
throw new NoSuchElementException();
return last.data;
}
/**
Removes the first element in the linked list.
#return the removed element
*/
public Object removeFirst()
{
//. . .
if (last == null)
throw new NoSuchElementException();
Object element = last.data;
last = last.next;
return element;
}
/**
Adds an element to the front of the linked list.
#param element the element to add
*/
public void addFirst(Object element)
{
//. . .
Node newNode = new Node();
newNode.data = element;
newNode.next = last;
last = newNode;
}
/**
Adds an element to the end of the linked list.
#param element the element to add
*/
public void add(Object element)
{
//. . .
if (last == null)
{
addFirst(element);
//position = last;//had to comment out
}
else
{
Node newNode = new Node();
newNode.data = element;
newNode.next = last.next;
last.next = newNode;
last = newNode;
}
}
/**
Returns an iterator for iterating through this list.
#return an iterator for iterating through this list
*/
public ListIterator listIterator()
{
return new LinkedListIterator();
}
private class Node
{
public Object data;
public Node next;
}
private class LinkedListIterator implements ListIterator
{
private Node position;
private Node previous;
/**
Constructs an iterator that points to the front
of the linked list.
*/
public LinkedListIterator()
{
position = null;
previous = null;
}
/**
Moves the iterator past the next element.
#return the traversed element
*/
public Object next()
{
//. . .
if (!hasNext())
throw new NoSuchElementException();
previous = position; //remeber for remove
if (position == null)
position = last;
else
position = position.next;
return position.data; //correct line
}
/**
Tests if there is an element after the iterator
position.
#return true if there is an element after the iterator
position
*/
public boolean hasNext()
{
//. . .
if (position == null)
return last != null;
else
return position.next !=null;
}
/**
Adds an element before the iterator position
and moves the iterator past the inserted element.
#param element the element to add
*/
public void add(Object element)
{
//. . .
if (position == null)
{
addFirst(element);
position = last;
}
}
/**
Removes the last traversed element. This method may
only be called after a call to the next() method.
*/
public void remove()
{
//. . .
if (previous == position)
throw new IllegalStateException();
if (position == last)
{
removeFirst();
}
else
{
previous.next = position.next;
}
position = previous;
}
/**
Sets the last traversed element to a different
value.
#param element the element to set
*/
public void set(Object element)
{
if (position == null)
throw new NoSuchElementException();
position.data = element;
}
}
}
Below code will help you to create Circular Linked List
class CircularLinkedList
{
class Node
{
int data;
Node next, prev;
public Node(int data)
{
this.data = data;
}
}
private Node head;
private int count;
public Node getHead()
{
return head;
}
public int getCount()
{
return count;
}
public boolean isEmpty()
{
return head==null;
}
// Add new node after the "head"
public void add(int data)
{
Node n = new Node(data);
if(isEmpty())
{
head = n;
n.next = head;
n.prev = head;
}
else
{
n.next = head.next;
n.prev = head;
head.next = n;
n.next.prev = n;
}
count++;
}
// Remove the node pointed by "head"
public void remove()
{
if(isEmpty())
return;
if(count==1)
head = null;
else
{
Node tmp = head;
tmp.prev.next = tmp.next;
tmp.next.prev = tmp.prev;
head = head.next;
tmp.next = tmp.prev = null;
}
count--;
}
public void print()
{
Node tmp = head.next;
while(tmp!=head)
{
System.out.println(tmp.data+" ");
tmp = tmp.next;
}
}
}
The above code will give you an idea how circular linked list is created, nodes are added, printed and deleted.
NOTE: As it's your assignment so I have not provided you with the exact code. You may use this and understand and tweak it in the way you require. By this you will have nice idea about Circular Linked List
If you have any issues ahead. Ask us. SO always welcome you :)

Categories