exception with java data structure - java

I am writing a generic data structure that can add and delete from the first or last nodes
I tested my code however I got exceptions in some certain way of input.
now if I addlast then addfirst then removelast i got exception
and when I addfirst many time without adding last then try to remove them by removelast() function i got exception
but when I addlast many time without adding first then remove them by removefirst() it works
I am trying to avoid while loops here is the code
import java.util.Iterator;
public class Deque <Item> implements Iterable <Item> {
private Node first,last;
private class Node
{
Item item;
Node next;
Node prev;
}
public Deque()
{
first = null;
last = null;
}
public boolean IsEmpty()
{
return first == null;
}
public void addFirst(Item item)
{
Node oldfirst = first;
first = new Node();
first.item = item;
first.next = oldfirst;
first.prev = null;
if (last == null)
{
last = first;
}
}
public void addlast(Item item)
{
Node oldlast = last;
last = new Node();
last.item = item;
last.next = null;
if (first == null)
{
first = last;
}
else
{
last.prev = oldlast;
oldlast.next = last;
}
}
public Item removeFirst()
{
Item x = first.item;
first = first.next;
if (IsEmpty())
last = null;
return x;
}
public Item removeLast()
{
if (first == last)
return removeFirst();
Item x = last.item;
last = last.prev;
last.next = null;
if (IsEmpty())
first = null;
return x;
}
public Iterator<Item> iterator ()
{
return new ListIterator();
}
private class ListIterator implements Iterator<Item>
{
private Node current = first;
public boolean hasNext ()
{
return current != null;
}
public void remove()
{
//NOt Supported
}
public Item next()
{
Item x = current.item;
current = current.next;
return x;
}
}
}
I believe I have something wrong with last.prev in removelast() since it is already null and then referred last = last.perv in remove()
but i couldnt think of a way to link last to last node of first
can anyone help me with this
here is the main if you want to try...
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Deque<Integer> o = new Deque<Integer>();
int num = 0;
while (true)
{
StdOut.println("enter 1 to addfirst, 2 addlast, 3 removefirst, 4 removelast, " +
"5 to exit");
num = StdIn.readInt();
if (num == 5)
break;
switch (num)
{
case 1:
StdOut.println("enter number to add first");
int x = StdIn.readInt();
o.addFirst(x);
break;
case 2:
StdOut.println("enter number to add last");
int y = StdIn.readInt();
o.addlast(y);
break;
case 3:
int w=o.removeFirst();
StdOut.print("the deleted number is: ");
StdOut.print(w);
StdOut.println();
break;
case 4:
int z=o.removeLast();
StdOut.print("the deleted number is: ");
StdOut.print(z);
StdOut.println();
break;
default:
StdOut.println("Stick with the range!");
break;
}
for (Iterator<Integer> i=o.iterator(); i.hasNext();)
{
StdOut.print(i.next());
StdOut.print(" ");
}
StdOut.println();
}
}
}

You have missed a couple of operations. In addFirst you don't set oldFirst.prev = first;, so if you add nodes with it, you won't have any prev references defined. That is why removeLast fails. It attempts to clean traverse to last.prev, but since everything was added with addFirst, last.prev is null.
Also, in removeFirst, you have a similar issue, that you don't remove the link to the former prev node, such as first.prev = null; Without doing that, if you were traversing using prev references, you would be able to move beyond the first node, after having called removeFirst.
addLast and addFirst should do, in essence, exactly the same things, just at different ends of the list. addFirst looks simpler, in your implementation, which means either you missed something in addFirst, or addLast is overly complex. In this case, you missed something in addFirst. Same with the remove methods.

Related

Steque and the API implementations

A steque is a stack-ended queue which is a data type that implements push, pop, and enqueue along with any other features that you wish to add to.
Note that I am implementing the steque with linked-list-based approach. Below is the code for my entire Steque class, the problem I have is whenever I try popping some element from the steque or to iterate through it I get the NullPointerException. The push() and enqueue() method seem to work just fine as I tested and I did thoroughly check my pop() and iterator() but can't seem to find any possible errors that might cause any NullPointerException. Any help on my code as how to resolve this will be greatly appreciated!
public class Steque<Item> implements Iterable<Item> {
private int N;
private Node first;
private Node last;
private class Node {
private Item item;
private Node next;
private Node prev;
}
/**
* create an empty steque
*/
public Steque() {
N = 0;
first = null;
last = null;
}
/**
* pop (return) the first item on top of stack and modify first
* accordingly to refer to next node.
*/
public Item pop() {
if (isEmpty()) throw new RuntimeException("Steque underflow");
Item item = first.item;
first = first.next;
N--;
return item;
}
/**
* push item on top of the stack and modify the first pointer
* to refer to the newly added item.
*/
public void push(Item item) {
Node oldfirst = first;
Node first = new Node();
first.item = item;
first.next = oldfirst;
if (oldfirst != null)
oldfirst.prev = first;
++N;
}
/**
* push item on bottom of the stack and reset the last pointer
* to refer to the newly added item.
*/
public void enqueue(Item item) {
Node oldlast = last;
Node last = new Node();
last.item = item;
last.prev = oldlast;
if (oldlast != null)
oldlast.next = last;
++N;
}
public Item peek() {
if (isEmpty()) throw new RuntimeException("Steque underflow");
return first.item;
}
public boolean isEmpty() {
return N == 0;
}
public int size() {
return N;
}
/**
* prints the steque from top to bottom
private void printState() {
System.out.println("Printing steque below: top --> bottom ");
for (Node idx = this.first; idx!= null; idx = idx.next) {
System.out.print(idx.item + " - ");
}
System.out.println();
}
*/
public String toString() {
StringBuilder s = new StringBuilder();
for (Item i : this) {
s.append(i + " ");
}
return s.toString().trim();
}
public Iterator iterator() {
return new LIFOIterator();
}
/**
* iterator that implements hasNext(), next(), and remove().
*/
private class LIFOIterator implements Iterator<Item>
{ // support LIFO iteration
private Node current = first;
public boolean hasNext() { return current.next != null; }
public void remove() {
Node n = first;
while (n.next.next != null) {
n = n.next;
}
n.next = null;
--N;
}
public Item next() {
if (!hasNext())
throw new NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
/**
* a simple test client
*/
public static void main(String[] args) {
Steque<String> steq = new Steque<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) {
//steq.push(item);
steq.enqueue(item);
}
/*
else if (!steq.isEmpty()) {
System.out.print(steq.pop() + " ");
}
*/
}
System.out.println("(" + steq.size() + " left on steque)");
Iterator itr = steq.iterator();
System.out.println("printing steque of strins below: ");
while(itr.hasNext()) {
System.out.print(itr.next() + " ");
}
}
}
Note: I am omitting all the import statements here but they are indeed included in my program so there is guaranteed to be no "undefined method" or "undeclared identifier" error in this code.
The problem is, that your first variable does not get filled when you only use the enqueue method.
Therefore the methods that access this field fire an NPE.
hasNext uses the field via current.
IMO the solution would be to catch the special for N == 0 in enqeue and fill the first element with the available element.
I tried
if(N==0)
first = last
after the initialisation of last in enqeue and it works without NPE.

Circular Doubly Linked List

I need help with a Circular Doubly Linked List in Java.
This is my code (originally coded by "sanfoundry"; it uses interfaces):
LinkedList.java:
public class LinkedList<T extends Comparable<T>> implements
ILinkedList<T> {
private ILinkedListNode<T> head;
private ILinkedListNode<T> end;
private int size;
public LinkedList() {
head = null;
end = null;
head = null;
size = 0;
}
#Override
public void append(T element) {
ILinkedListNode<T> tempNode = new LinkedListNode(element, null, null);
if (head == null) {
head = tempNode;
end = head;
} else {
tempNode.setPrev(end);
tempNode.setNext(tempNode);
end = tempNode;
}
size++;
}
// should return element at position "index"
#Override
public T get(int index) {
return null;
}
#Override
public int size() {
return size;
}
#Override
public ILinkedListNode<T> getHead() {
return head;
}
}
Now I need help to get it working. Did I do something wrong and what do I have to code in method "public T get (int index)"? Sorry, but I'm a Java noob :(
EDIT: Is this a possible solution?
public T get(int index) {
T element = null;
if (index == 0) {
element = head.getElement();
} else if (index == size()-1) {
element = head.getPrev().getElement(); // end.getElement() also possible
} else {
ILinkedListNode<T> temp = head;
for (int i = 0; i < index; i++) {
temp = temp.getNext();
}
element = temp.getElement();
}
return element;
}
You should traverse the LinkedList, keeping track of your current position as you go. When your current position is equal to the index passed in, then you can return the T from that node.
Read about traversing a linked list here.
Try making some test cases. Ideally you'll want to use a real test framework but using a normal main method could work. For example:
public static void main(String[] args) {
ILinkedList<String> a = new LinkedList<String>();
System.out.println(a.size()); // 0
System.out.println(a.getHead()); // null
a.append("foo");
System.out.println(a.size()); // 1
System.out.println(a.get(0)); // "foo"
System.out.println(a.get(1)); // decide yourself what this should result in
a.append("bar");
System.out.println(a.size()); // 2
System.out.println(a.get(0)); // "foo"
System.out.println(a.get(1)); // "bar"
a.append("baz");
System.out.println(a.size()); // 3
System.out.println(a.get(0)); // "foo"
System.out.println(a.get(1)); // "bar"
System.out.println(a.get(2)); // "baz"
}
Expand the test as necessary. See if the code returns what you expect it to, or if the code never returns, or throws an exception, etc.... The easiest way to check whether your code is running properly is, after all, to actually run it.
Hint: the code, as of this writing, has some errors.
Also, if the code can run as expected, consider:
Traversing the nodes backward if it's faster than forward.
Using a recursion instead of iteration.

Java Using Nodes with LinkedList

I've been working through some standard coding interview questions from a book I recently bought, and I came across the following question and answer:
Implement an algorithm to find the nth to last element in a linked list.
Here's the provided answer:
public static LinkedListNode findNtoLast(LinkedListNode head, int n) { //changing LinkedListNode to ListNode<String>
if(head == null || n < 1) {
return null;
}
LinkedListNode p1 = head;
LinkedListNode p2 = head;
for(int j = 0; j < n-1; ++j) {
if(p2 == null) {
return null;
}
p2 = p2.next;
}
if(p2 == null) {
return null;
}
while(p2.next != null) {
p1 = p1.next;
p2 = p2.next;
}
return p1;
}
I understand the algorithm, how it works, and why the book lists this as its answer, but I'm confused about how to access the LinkedListNodes to send as an argument to the method. I know that I'd have to create a LinkedListNode class (since Java doesn't already have one), but I can't seem to figure out how to do that. It's frustrating because I feel like I should know how to do this. Here's something that I've been working on. I'd greatly appreciate any clarification. You can expand/comment on my code or offer your own alternatives. Thanks.
class ListNode<E> {
ListNode<E> next;
E data;
public ListNode(E value) {
data = value;
next = null;
}
public ListNode(E value, ListNode<E> n) {
data = value;
next = n;
}
public void setNext(ListNode<E> n) {
next = n;
}
}
public class MyLinkedList<E> extends LinkedList {
LinkedList<ListNode<E>> list;
ListNode<E> head;
ListNode<E> tail;
ListNode<E> current;
ListNode<E> prev;
public MyLinkedList() {
list = null;
head = null;
tail = null;
current = null;
prev = null;
}
public MyLinkedList(LinkedList<E> paramList) {
list = (LinkedList<ListNode<E>>) paramList; //or maybe create a loop assigning each ListNode a value and next ptr
head = list.getFirst();
tail = list.getLast(); //will need to update tail every time add new node
current = null;
prev = null;
}
public void addNode(E value) {
super.add(value);
//ListNode<E> temp = tail;
current = new ListNode<E>(value);
tail.setNext(current);
tail = current;
}
public LinkedList<ListNode<E>> getList() {
return list;
}
public ListNode<E> getHead() {
return head;
}
public ListNode<E> getTail() {
return tail;
}
public ListNode<E> getCurrent() {
return current;
}
public ListNode<E> getPrev() {
return prev;
}
}
How can the LinkedListNode head from a LinkedList?
Update: I think part of my confusion comes from what to put in the main method. Do I need to create a LinkedList of ListNode? If I do that, how would I connect the ListNodes to each other? How would I connect them without using a LinkedList collection object? If someone could show me how they would code the main method, I think that would put things into enough perspective for me to solve my issues. Here's my latest attempt at the main method:
public static void main(String args[]) {
LinkedList<ListNode<String>> list = new LinkedList<ListNode<String>>();
//MyLinkedList<ListNode<String>> list = new MyLinkedList(linkedList);
list.add(new ListNode<String>("Jeff"));
list.add(new ListNode<String>("Brian"));
list.add(new ListNode<String>("Negin"));
list.add(new ListNode<String>("Alex"));
list.add(new ListNode<String>("Alaina"));
int n = 3;
//ListIterator<String> itr1 = list.listIterator();
//ListIterator<String> itr2 = list.listIterator();
LinkedListNode<String> head = new LinkedListNode(list.getFirst(), null);
//String result = findNtoLast(itr1, itr2, n);
//System.out.println("The " + n + "th to the last value: " + result);
//LinkedListNode<String> nth = findNtoLast(list.getFirst(), n);
ListNode<String> nth = findNtoLast(list.getFirst(), n);
System.out.println("The " + n + "th to the last value: " + nth);
}
In an attempt to connect the nodes without using a custom linked list class, I have edited my ListNode class to the following:
class ListNode<E> {
ListNode<E> next;
ListNode<E> prev; //only used for linking nodes in singly linked list
ListNode<E> current; //also only used for linking nodes in singly linked list
E data;
private static int size = 0;
public ListNode() {
data = null;
next = null;
current = null;
if(size > 0) { //changed from prev != null because no code to make prev not null
prev.setNext(this);
}
size++;
}
public ListNode(E value) {
data = value;
next = null;
current = this;
System.out.println("current is " + current);
if(size > 0) {
prev.setNext(current);//this line causing npe
}
else
{
prev = current;
System.out.println("prev now set to " + prev);
}
size++;
System.out.println("after constructor, size is " + size);
}
public ListNode(E value, ListNode<E> n) {
data = value;
next = n;
current = this;
if(size > 0) {
prev.setNext(this);
}
size++;
}
public void setNext(ListNode<E> n) {
next = n;
}
}
As is right now, the program will run until it reaches prev.setNext(current); in the single argument constructor for ListNode. Neither current nor prev are null at the time this line is reached. Any advice would be greatly appreciated. Thanks.
You don't actually need a separate LinkedList class; the ListNode class is a linked list. Or, to state it differently, a reference to the head of the list is a reference to the list.
The use of head, tail, current, prev in the sample code you posted has come from a double-linked list which is a data type that has links in both directions. This is more efficient for certain types of applications (such as finding the nth last item).
So I would recommend renaming your ListNode class to LinkedList and renaming next to tail.
To add a new item to the list you need a method that creates a new list with the new item at it's head. Here is an example:
class LinkedList<E> {
...
private LinkedList(E value, LinkedList<E> tail) {
this.data = value;
this.tail = tail;
}
public LinkedList<E> prependItem(E item) {
return new LinkedList(item, this);
}
}
Then to add a new item i to list you use list = list.prependItem(i);
If for some reason you need to always add the items to the end, then:
private LinkedList(E value) {
this.data = value;
this.tail = null;
}
public void appendItem(E item) {
LinkedList<E> list = this;
while (list.tail != null)
list = list.tail;
list.tail = new LinkedList<>(item);
}
However this is obviously pretty inefficient for long lists. If you need to do this then either use a different data structure or just reverse the list when you have finished adding to it.
Incidentally, an interesting side effect of this is that a reference to any item in the list is a reference to a linked list. This makes recursion very easy. For example, here's a recursive solution for finding the length of a list:
public int getLength(LinkedList list) {
if (list == null) {
return 0;
} else {
return 1 + getLength(list.getTail());
}
}
And using this a simple (but very inefficient!) solution to the problem you provided - I've renamed the method to make its function more obvious:
public LinkedList getTailOfListOfLengthN(LinkedList list, int n) {
int length = getLength(list);
if (length < n) {
return null;
} else if (length == n) {
return list;
} else {
return getTailOfLengthN(list.getTail(), n);
}
}
And to reverse the list:
public LinkedList<E> reverse() {
if (tail == null) {
return this;
} else {
LinkedList<E> list = reverse(tail);
tail.tail = this;
tail = null;
return list;
}
}
As I hope you can see this makes the methods a lot more elegant than separating the node list classes.
Actually you have created a linked list with you class ListNode.
A linked list is made of a node and a reference to another linked list (see the recursion?).

Why is my doubly linked list removing previous links?

I Know this topic has been beat to death but I'm really struggling with implementing these two add methods to a linked list. addFirst and addLast both work when called by themselves but when I call addFirst("foo") and addLast("bar") the add last removes anything previously added to the list. add first is supposed to add an item to the beginning of the list, and add last is supposed to append it to the end.
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Deque<Item> implements Iterable<Item> {
private int N;
private Node first;
private Node last;
//create linked list
private class Node
{
String item;
Node next;
Node previous;
}
public Deque() // construct an empty deque
{
N = 2;
first = new Node();
last = new Node();
//link together first and last node;
first.next = last;
last.previous = first;
last.item = "Last";
first.item = "First";
}
public boolean isEmpty() // is the deque empty?
{
return first == null;
}
public int size() // return the number of items on the deque
{
return N;
}
public void addFirst(Item item) // insert the item at the front
{
Node nextElement = new Node();
nextElement.item = (String)item;
nextElement.next = first.next;
nextElement.previous = first;
first.next = nextElement;
N++;
}
public void addLast(Item item) // insert the item at the end
{
Node newLast = new Node();
newLast.item = (String)item;
newLast.next = last;
newLast.previous = last.previous;
last.previous.next = newLast;
last.previous = newLast;
N++;
}
public void printList()
{
Node print = first;
for (int i = 0; i < N; i++)
{
System.out.print(print.item);
print = print.next;
}
System.out.println("");
}
Seems like you're getting yourself confused. Generally, if your doing something.next.next or similar, a warning should go off in your head. You'd also be well served to provide a constructor that could take the item instead of the addition statement in the method.
public void addLast(Item item) // insert the item at the end
{
Node newLast = new Node();
newLast.item = (String)item;
if (isEmpty()) {
first = newLast;
} else {
last.next = newLast;
newLast.previous = last;
}
last = newLast;
N++;
}
As far as addFirst is concerned, so you don't inadvertently get bad advice, it would go something like this...
public void addFirst(Item item) {
Node newFirst = new Node();
newFirst.item = (String)item;
if (isEmpty()) {
last = newFirst;
} else {
first.previous = newFirst;
}
newFirst.next = first;
first = newFirst;
N++;
}
The addfirst method is missing updating one of the pointers
public void addFirst(Item item) // insert the item at the front
{
Node nextElement = new Node();
nextElement.item = (String)item;
nextElement.next = first.next;
nextElement.previous = first;
first.next.previous = nextElement; //ADDED HERE
first.next = nextElement;
N++;
}
I think this question is answered with one simple link - you're re-inventing the wheel which is always a bad idea, no matter what educational purposes your goals serve.
Use the Deque interface.

Implement a Stack with a circular singly linked list

I'm trying to implement the a Stack in Java with a circular singly linked list as the underlying data structure. I placed the insert function for a circular linked list in replacement of the push function for the stack and so on. I don't have any errors but I'm having troubles displaying the stack. If anyone could point me in the right direction of how to display the stack or what's going wrong I'd really appreciate it!
Here is my stack class:
public class Stack {
private int maxSize; // size of stack array
private long[] stackArray;
private int top; // top of stack
private Node current = null; // reference to current node
private int count = 0; // # of nodes on list
private long iData;
public Stack(int s) // constructor
{
maxSize = s; // set array size
stackArray = new long[maxSize]; // create array
top = -1; // no items yet
}
public void push(long j) // put item on top of stack
{
Node n = new Node(j);
if(isEmpty()){
current = n;
}
n.next = current;
current = n;
count++;
}
//--------------------------------------------------------------
public Node pop() // take item from top of stack
{
if(isEmpty()) {
return null;
}
else if(count == 1){
current.next = null;
current = null;
count--;
return null;
}else{
Node temp = current;
current = current.next;
temp.next = null;
temp = null;
count--;
}
return current;
}
//--------------------------------------------------------------
public Node peek(long key) // peek at top of stack
{
Node head = current;
while(head.iData != key){
head = head.next;
}
return head;
}
//--------------------------------------------------------------
public boolean isEmpty() // true if stack is empty
{
return (count == 0);
}
//--------------------------------------------------------------
public boolean isFull() // true if stack is full
{
return (count == maxSize-1);
}
//--------------------------------------------------------------
Here is my constructor class
public class Node{
public long iData; // data item (key)
public Node next; // next node in the list
public Node(long id){ // constructor
iData = id; // next automatically nulls
}
public void displayNode(){
System.out.print(iData + " ");
}
public static void main(String[] args) {
Stack newlist = new Stack(3);
newlist.push(1);
newlist.push(2);
newlist.push(3);
newlist.push(4);
newlist.pop();
newlist.pop();
newlist.push(4);
newlist.pop();
newlist.peek(1);
newlist.push(5);
while( !newlist.isEmpty() ) // until it’s empty,
{ // delete item from stack
Node value = newlist.pop();
System.out.print(value); // display it
System.out.print(" ");
} // end while
System.out.println("");
}
//newlist.displayList();
}
First, in your main function you are printing value using System.out.print function. This displays the object's class name representation, then "#" followed by its hashcode.
Replace following lines
System.out.print(value); // display it
System.out.print(" ");
with
value.displayNode();
Second, in pop method, you are returning null when count is 1. It should return the last element which is present in the list. Also, in last else if clause, you should return temp. Replace your code with this.
public Node pop() // take item from top of stack
{
if (isEmpty()) {
return null;
}
Node temp = current;
if (count == 1) {
current = null;
} else {
current = current.next;
}
count--;
temp.next = null;
return temp;
}
A few notes on your implementation:
1) stackArray member seems to be a leftover from another array based stack implementation.
2) is max size really a requirement? if so, you don't enforce the stack size limitation in push(..)
3) Your push(..) method doesn't keep the list circular. You should close the loop back to the new node.
4) Adding a dummy node allows you to keep the linked list circular, regardless of the stack size. This can make your push(..) method simpler (as well as any iteration for printing purposes for example)
5) The peek() method contract is unclear. Usually you want the peek method to return the value in the top of the stack, without removing it. Also, why do you return type Node? This class should be hidden from the caller - it's an internal implementation detail, not something you want to expose in your API.
Following is an alternative implementation, that also supports toString():
public class Stack {
private Node EOS;
private int count = 0;
public Stack() {
EOS = new Node(0);
EOS.next = EOS;
}
public void push(long j) {
Node newNode = new Node(j);
Node tmp = EOS.next;
EOS.next = newNode;
newNode.next = tmp;
count++;
}
public Long pop() {
if (isEmpty()) {
return null;
} else {
count--;
Node node = EOS.next;
EOS.next = node.next;
return node.iData;
}
}
public Long peek() {
if (isEmpty()) {
return null;
} else {
Node node = EOS.next;
return node.iData;
}
}
public boolean isEmpty() {
return (count == 0);
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
Node p = EOS.next;
while (p != EOS) {
sb.append(p).append("\n");
p = p.next;
}
return sb.toString();
}
private static class Node {
public long iData;
public Node next;
public Node(long id) {
iData = id;
}
#Override
public String toString() {
return "<" + iData + ">";
}
}
}

Categories

Resources