I am trying to implement the stack i.e., DSAStack.java using my linked list i.e., DSALinkedList.java
How do I do it? I think I am supposed to have push() perform an insertFirst() and pop() do a peekFirst() and removeFirst() to get the LIFO behaviour? and what about isEmpty()
and the other methods?
I am not sure, please help me out. A clear explanation with a code would be much appreciable. Thank you in advance!
Here is the DSAStack.java
public class DSAStack implements Iterable {
public static int DEFAULT_CAPACITY = 100;
private DSALinkedList list;
private int count;
private Object[] stack;
public DSAStack() {
count = 0;
stack = new Object[DEFAULT_CAPACITY];
}
public DSAStack(int maxCapacity) {
count = 0;
stack = new Object[maxCapacity];
}
public int getCount() {
return count;
}
public boolean isEmpty() {
boolean empty = (count == 0);
return empty;
}
public boolean isFull() {
boolean full = (count == stack.length);
return full;
}
public void push(Object value) {
if (isFull())
throw new IllegalArgumentException("Stack is full");
else
stack[count] = value;
count++;
}
public Object pop() {
Object topVal = top();
count--;
return topVal;
}
public Object top() {
Object topVal;
if (isEmpty())
throw new IllegalArgumentException("Stack is empty");
else
topVal = stack[count-1];
return topVal;
}
public Iterator iterator() {
return list.iterator();
}
}
AND here is the DSALinkedList.java
import java.util.*;
public class DSALinkedList {
public DSAListNode head;
public DSAListNode tail;
Object[] newValue;
public DSALinkedList() {
head = null;
tail = null;
}
public void insertFirst(Object newValue){
DSAListNode newNd;
newNd = new DSAListNode(newValue);
if (head == null) {
head = newNd;
tail = newNd;
} else {
newNd.setNext(head);
head = newNd;
}
}
public void insertLast(Object newValue){
DSAListNode newNd;
newNd = new DSAListNode(newValue);
if(head == null){
head = newNd;
} else {
tail.next = newNd;
tail = newNd;
}
}
public boolean isEmpty() {
return (head == null);
}
public Object peekFirst(){
Object nodeValue;
if (head == null)
throw new IllegalArgumentException("head is empty");
else
nodeValue = head.getValue();
return nodeValue;
}
public Object peekLast(){
Object nodeValue;
if (head == null)
throw new IllegalArgumentException("head is empty");
else
nodeValue = tail.getValue();
return nodeValue;
}
public Object removeFirst(){
Object nodeValue;
if (head == null){
throw new IllegalArgumentException("head is empty");
} else {
nodeValue = head.getValue();
head = head.getNext();
}
return nodeValue;
}
}
Your DSAStack class is meant to be the interface between the user and linkedlist. So therefore the class provides the LIFO interface and forces it on the user. From here, it should hide the implementation from the linkedlist so the user doesn't have to worry about insertingLast or insertingFirst, they just want to insert.
So to answer your question. The DSAStack needs to perform the following actions:
- size() -> returns int size
- push(Object e) -> returns bool (able to be inserted)
- pop() -> returns Object and removes it from linkedlist
- peek() -> returns Object
- isEmpty() -> returns bool if empty
Your DSAStack isn't meant to hold any data. So you don't need the count or stack variable. Instead, we need to store these inside the DSALinkedList class. DSAStack should therefore instantiate a DSALinkedList object, pass the maxCapacity, and initiate the object.
When the user says that they want to use pop() on DSAStack, the class then needs to tell DSALinkedList, hey! I want to pop one of your objects! Now DSALinkedList needs to implement the details here.
Rewriting your code would be like this:
public DSAStack(int maxCapacity) {
list = new DSALinkedList[maxCapacity];
}
public int getCount() {
return list.size();
}
public boolean isEmpty() {
return list.isEmpty();
}
public boolean isFull() {
return list.isFull();
}
public void push(Object value) {
list.insertLast(value);
}
public Object pop() {
return list.removeLast();
}
public Object top() {
return list.peekLast();
}
public Iterator iterator() {
return list.iterator();
}
}
Related
Implementing LinkedList in a recursive approach was a bit challenging to me, which I get stuck in implementing of its remove method and wonder how to keep reference to previous item in recursive?
MyLinkedList class
package linkedlist;
public class MyLinkedList {
private Integer value;
private MyLinkedList next;
public MyLinkedList() {
}
public MyLinkedList(Integer value) {
this.value = value;
}
public void add(Integer value) {
if (this.value == null) {
this.value = value;
} else if (this.next == null) {
this.next = new MyLinkedList(value);
} else {
this.next.add(value);
}
}
public MyLinkedList remove(Integer index) {
//
// if (index < 0) {
// return this;
// }
// if (index == 0) {
// return this.next;
// }
// this.next = remove(index - 1);
return this;
}
public Integer indexOf(Integer value) {
if (this.value.equals(value)) {
return 0;
} else if (this.next == null) {
return null;
} else {
return 1 + this.next.indexOf(value);
}
}
}
MyLinkedListTester class
package linkedlist;
public class MyLinkedListTester {
public static void main(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.add(1);
myLinkedList.add(2);
myLinkedList.add(3);
myLinkedList.add(4);
System.out.println("Index Of Array: " + myLinkedList.indexOf(3));
MyLinkedList linkedList = myLinkedList.remove(3);
}
}
As mentioned in the comments the iterative approach is easier and more efficient most of the time. Anyway I think you do this as an exercise because in Java you already have a LinkedList.
So first you have a kind of error in your thinking (as far as I'm aware of it). It's also a kind of bad design choice. You create your MyLinkedList and save the data right into it and the next is also of the class MyLinkedList but it's not a list, it's a Node. There should only be one List, and 0 - many nodes.
For example I can't figure out how to do a remove function that will return the removed Node (in your case MyLinkedList) and as well let you keep the list in case you remove the first element in your list.
If you are looking in the implementation that's why they use Nodes and it's also more logical (a list doesn't contain "List elements") and so on...
Some other remark: your indexOf funtion will return an error if you try to get a element that does not exist (1 + null => error).
So anyway. What you have to do is to create a Node. (btw if you really want a real LinkedList you can use generic instead of int/Integer).
Below I post my solution how to do it (may be better out there but that is how I would do it). I also wrote a toString method to see how the List looks like (and it works as far as I can say). In case you want to still use your code without the Node it should give you an idea how to solve your problem with remove. You can also put some of the logic into the Node class but for me Node is only a container and doesn't really contain any logic.
public class MyLinkedList {
private Node head;
public MyLinkedList() {
}
public class Node{
private int value;
private Node next = null;
public Node(int value){
this.value = value;
}
public int getValue(){
return value;
}
public Node getNext(){
return next;
}
public void setNext(Node next){
this.next = next;
}
}
public void add(int value) {
Node next = new Node(value);
if(head == null){
head = next;
} else {
addRecursive(head,next);
}
}
private void addRecursive(Node node, Node next) {
if(node.next == null){
node.setNext(next);
} else {
addRecursive(node.getNext(),next);
}
}
public Node remove(int index){
Node removeNode = head;
if(index == 0){
head = head.getNext();
} else {
removeNode = removeRecursive(head,index-1);
}
return removeNode;
}
private Node removeRecursive(Node node, int index){
Node removeNode = node.getNext();
if(index == 0){
node.setNext(removeNode.getNext());
} else {
removeNode = removeRecursive(node.getNext(),index-1);
}
return removeNode;
}
public int indexOf(int value) {
if (head == null){
return -1;
} else if (head.getValue() == value){
return 0;
} else {
return indexOfRecursive(head,value,0);
}
}
private int indexOfRecursive(Node node, int value, int index) {
if(node.getNext() == null){
return -1;
} else if(node.getNext().getValue() == value){
return index + 1;
} else {
return indexOfRecursive(node.getNext(),value,index+1);
}
}
#Override
public String toString(){
if(head == null){
return "";
} else {
return toStringRecursive(head,"["+head.getValue());
}
}
private String toStringRecursive(Node node, String output){
if(node.getNext() == null){
return output + "]";
} else {
return toStringRecursive(node.getNext(),output + ", " + node.getNext().getValue());
}
}
}
I am trying to print the first and last elements in a deque using a toString method however I'm not entirely sure if I am overwriting the toString method correctly.
As far as I can tell, the methods all seem to behave correctly but I have no way of being able to tell as I am unable to see any readable output.
I am aware that there is already a deque interface, however this is part of an exercise in using generics in Java.
This piece of code should create a deque, be able to add values to the front of the deque, remove values from the front, add values to the rear and remove values from the rear.
Here's the class in question:
import java.util.Iterator;
import java.util.NoSuchElementException;
class Deque<T> implements Iterable<T> {
private class Node<T> {
public Node<T> left, right;
private final T item;
public Node(T item) {
if (item == null) {
throw new NullPointerException();
}
this.item = item;
}
public void connectRight(Node<T> other) {
this.right = other;
other.left = this;
}
}
private class DequeIterator implements Iterator<T> {
private Node<T> curr = head;
public boolean hasNext() {
return curr != null;
}
public void remove() {
throw new UnsupportedOperationException();
}
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
T item = curr.item;
curr = curr.right;
return item;
}
}
private Node<T> head, tail;
private int size;
public Iterator<T> iterator() {
return new DequeIterator();
}
public Deque() {
}
public int size() {
return size;
}
public boolean isEmpty() {
return size() == 0;
}
public void checkInvariants() {
assert size >= 0;
assert size > 0 || (head == null && tail == null);
assert (head == null && tail == null) || (head != null && tail != null);
}
public void addFirst(T item) {
Node<T> prevHead = head;
Node<T> newHead = new Node<T>(item);
if (prevHead != null) {
newHead.connectRight(prevHead);
} else {
tail = newHead;
}
head = newHead;
size++;
checkInvariants();
}
public void addLast(T item) {
Node<T> newTail = new Node<T>(item);
Node<T> prevTail = tail;
if (prevTail != null) {
prevTail.connectRight(newTail);
} else {
head = newTail;
}
tail = newTail;
size++;
checkInvariants();
}
public T removeFirst() {
if (isEmpty()) {
throw new java.util.NoSuchElementException();
}
size--;
Node<T> prevHead = head;
head = prevHead.right;
prevHead.right = null;
if (head != null) {
head.left = null;
}
checkInvariants();
return prevHead.item;
}
public T removeLast() {
if (isEmpty()) {
throw new java.util.NoSuchElementException();
}
size--;
Node<T> prevTail = tail;
tail = prevTail.left;
prevTail.left = null;
if (tail != null) tail.right = null;
checkInvariants();
return prevTail.item;
}
#Override
public String toString() {
Node<T> currTail = tail;
Node<T> currHead = head;
head = currHead.right;
tail = currTail.left;
StringBuilder builder = new StringBuilder();
while (currHead != null && currTail != null) {
builder.append(currHead.item + "\n");
}
return builder.toString();
}
public static void main(String[] args) {
Deque<Double> d = new Deque<Double>();
d.addFirst(1.0);
System.out.println(d);
d.addLast(1.0);
//d.removeFirst();
//d.removeLast();
System.out.println(d.toString());
}
}
First of all, you're setting the instance variables head and tail to their respective neighbours, which is definitely not what you're out to do. This leaves your queue in an inconsistent state, where the second element is the head, but it still has a left neighbour, the original head. Same thing for the tail. Generally the toString method shouldn't have side effects.
Neither currTail nor currHead ever change in your while-loop, so your condition currHead != null && currTail != null will always be true if the deque is non-empty. You'd have to set those variables in the loop, however, you don't need to iterate from both ends at once. Iterating from the start will be enough. And then, you can use a for loop, like this:
#Override
public String toString() {
final StringJoiner stringJoiner = new StringJoiner("\n");
for (Node<T> node = head; node != null; node = node.right) {
stringJoiner.add(node.item.toString());
}
return stringJoiner.toString();
}
This sets the variable node to it's right neighbour after every iteration, and if the deque is empty, node will be null from the get-go and the loop will not be entered as is expected.
This is just the more concise (In my opinion) version of this:
#Override
public String toString() {
final StringJoiner stringJoiner = new StringJoiner("\n");
Node<?> node = head;
while (node != null) {
stringJoiner.add(node.item.toString());
node = node.right;
}
return stringJoiner.toString();
}
which is basically your attempt, just fixed.
Not that I've used a StringJoiner instead of a StringBuilder, as it allows you to set a delimeter that is used between each String, which is exactly what you're doing.
So the idea is to make a Double Ended Priority Queue so far I have got a tree like structure using 2 Linked Lists, I have and interface I have to stick with with no alterations to it. The problem I have got is I have to make 2 methods called getMost and getLeast which gets the most or least node and then makes that node null. But these 2 methods are proving quite difficult to make. How would you go about doing it?
I have tried using recursion but this is proving difficult as I have to select the tree by going tree.root but passing in tree.root into a recursive method always starts it from tree.root
Also I have tried what i have written in inspectLeast() and inspectMost() but Java passes by value not by reference. Any tips?
P.S Not allowed to use anything from java collections or java util.
public class PAS43DPQ implements DPQ
{
//this is the tree
TreeNode tree = new TreeNode();
//this is for the size of the array
int size = 0;
#Override
public Comparable inspectLeast() {
return tree.inspectLeast(tree.root);
}
#Override
public Comparable inspectMost() {
return tree.inspectMost(tree.root);
}
#Override
public void add(Comparable c)
{
tree.add(c);
size++;
}
#Override
public Comparable getLeast() {
if (tree.root != null){
}
return getLeast();
}
#Override
public Comparable getMost(){
Comparable most = getMost();
return most;
}
#Override
public boolean isEmpty() {
return (size > 0)?true:false;
}
#Override
public int size() {
return this.size;
}
class TreeNode{
private Comparable value;
private TreeNode left, right, root;
//constructors
public TreeNode() {}
public TreeNode(TreeNode t) {
this.value = t.value;
this.left = t.left;
this.right = t.right;
this.root = t.root;
}
public TreeNode(Comparable c) {
this.value = (int) c;
}
public void add(Comparable input){
if(root == null){
root = new TreeNode(input);
return;
} else {
insert(root, input);
}
}
public Comparable inspectLeast(TreeNode n){
if (n == null)
return null;
if (n.left == null){
TreeNode least = n;
return least.value;
}
return inspectLeast(n.left);
}
public Comparable inspectMost(TreeNode n){
if (n == null)
return null;
if (n.right == null){
TreeNode most = n;
return most.value;
}
return inspectMost(n.right);
}
public Comparable getMost(TreeNode n){
if(n.right == null)
return n.value;
return tree.getMost(right);
}
public void insert(TreeNode n, Comparable input){
if(input.compareTo(n.value) >= 0){
if (n.right == null) {
n.right = new TreeNode(input);
return;
}
else
insert(n.right, input);
}
if(input.compareTo(n.value) < 0){
if(n.left == null) {
n.left = new TreeNode(input);
return;
}
else
insert(n.left, input);
}
}
}
}
You should be able to modify your TreeNode.getMost(TreeNode n) and TreeNode.getLeast(TreeNode n) similar to the following:
public class TreeNode{
// Also, your parameter here seems to be superfluous.
public TreeNode getMost(TreeNode n) {
if (n.right == null) {
n.root.right = null;
return n;
}
return n.getMost(n);
}
}
Get least should be able to be modified in a similar fashion, but using left rather than right obviously.
I am learning Java, and implementing a Deque data structure. This is the Node class:
import java.util.*;
public class Deque<Item> implements Iterable<Item> {
private Node sentinel;
private class Node {
Item item;
Node next;
Node previous;
Node(Item value) {
item = value;
next = this;
previous = this;
}
}
public Deque(Item item) // construct an empty deque
{
Node sentinel = new Node(item);
}
public boolean isEmpty() // is the deque empty?
{
return (size() == 0);
}
public int size() // return the number of items on the deque
{
System.out.println("size");
if (sentinel.next == sentinel) {
System.out.println("empty");}
return 0;
// }
// int count = 0;
// Node temp = sentinel;
// while (temp != sentinel)
// {
// count += 1;
// temp = temp.next;
// }
// return count;
}
public void addFirst(Item item) // insert the item at the front
{
if (item == null) {
throw new java.util.NoSuchElementException();
}
Node a = new Node(item);
if (isEmpty())
{
System.out.println("Hello world");
sentinel.next = a;
a.previous = sentinel;
}
else
{
sentinel.next.previous = a;
sentinel.next = a;
a.previous = sentinel;
}
}
public void addLast(Item item) // insert the item at the end
{
if (item == null)
throw new java.util.NoSuchElementException();
Node a = new Node(item);
sentinel.previous = a;
a.next = sentinel;
}
public Item removeFirst() // delete and return the item at the front
{
if (isEmpty())
throw new UnsupportedOperationException();
Item value = sentinel.next.item;
sentinel.next = sentinel.next.next;
sentinel.next.previous = sentinel;
return value;
}
public Item removeLast() // delete and return the item at the end
{
if (isEmpty())
throw new UnsupportedOperationException();
Item value = sentinel.previous.item;
sentinel.previous = sentinel.previous.previous;
sentinel.previous.next = sentinel;
return value;
}
public Iterator<Item> iterator() // return an iterator over items in order from front to end
{
return new DequeueIterator();
}
private class DequeueIterator implements Iterator<Item>
{
private Node current = sentinel;
public boolean hasNext() {
return current != null;
}
public void remove() {}
public Item next() {
Item value = current.item;
current = current.next;
return value;
}
}
public static void main(String[] args) // unit testing
{
System.out.println(Thread.currentThread().getStackTrace());
Deque<Integer> d = new Deque<Integer>(0);
System.out.println(d.isEmpty());
System.out.println(Thread.currentThread().getStackTrace());
// d.addFirst(10);
// System.out.println(d.size());
// System.out.println(d.removeLast());
}
}
Then when checking the size of the Deque as following:
public class Deque<Item> implements Iterable<Item> {
public Deque() // construct an empty deque
{
Node sentinel = new Node(null);
if (sentinel.next == sentinel)
System.out.println("empty");
}
}
The compiler error is NullPointerException. Is it due to the initialization of Node(null)? If yes, how can I input a zero value for the generic Item?
Stacktrace:
java.lang.NullPointerException
at Deque.size(Deque.java:29)
at Deque.isEmpty(Deque.java:24)
at Deque.main(Deque.java:111)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)
And line 29 is:
if (sentinel.next == sentinel)
You're declaring a local variable called sentinel and assigning it instead of using the instance field and assigning it.
public Deque(Item item) // construct an empty deque
{
Node sentinel = new Node(item);
}
should be
public Deque(Item item) // construct an empty deque
{
this.sentinel = new Node(item);
}
otherwise the instance variable sentinel remains null and causes a NullPointerException when you try to dereference it
public int size() // return the number of items on the deque
{
System.out.println("size");
if (sentinel.next == sentinel) { // here
System.out.println("empty");
}
return 0;
}
If you get a NullPointerException on the following line:
if (sentinel.next == sentinel)
then the only cause can possibly be that sentinel is null. This is because in the constructor for Deque, you are creating a new variable called sentinel, not using the one in the class.
I'm implementing a list interface with links but since "ListADT" implements the Iterable interface. So, I have to have a method that produces an iterator which I'm not sure how to do. I tried using it as it is now and when I created an object for the linkedlist, and then call the iterator() method, I get an overflow. I know the method is supposed to produce an Iterator object but not sure how.
import java.util.Iterator;
public class LinkedList<T> implements ListADT<T>
{
protected int count;
protected LinearNode <T> head, tail;
private int modCount;
public LinkedList()
{
count =0;
head = tail= null;
}
public T removeFirst()
{
T result = head.getElement();
head = head.getNext();
count--;
return result;
}
public T removeLast()
{
// THROW EMPTY EXCEPTION
T result;
LinearNode <T> previous = null;
LinearNode <T> current = head;
while(!current.equals(tail))
{
previous = current;
current = current.getNext();
}
result = tail.getElement();
tail = previous;
tail.setNext(null);
count--;
return result;
}
public T remove(T element)
{
// throw exception
boolean found = false;
LinearNode <T> previous = null;
LinearNode <T> current = head;
while (current != null && !found)
{
if(element.equals(current.getElement()))
found = true;
else
{
previous = current;
current = current.getNext();
}
if (!found)
{
}
else if (current.equals(head))
{
head = current.getNext();
}
else if(current.equals(tail))
{
tail = previous;
tail.setNext(null);
}
else
previous.setNext(current.getNext());
}
count --;
return current.getElement();
}
public T first()
{
return head.getElement();
}
public T last()
{
return tail.getElement();
}
public boolean contains(T target)
{
boolean found = false;
LinearNode <T> previous = null;
LinearNode <T> current = head;
while (current != null && !found)
{
if(target.equals(current.getElement()))
found = true;
else
{
previous = current;
current = current.getNext();
}
}
return found;
}
public boolean isEmpty()
{
boolean result = false;
if( head == null && tail ==null)
{
result = true;
}
return result;
}
public int size()
{
return count;
}
public Iterator<T> iterator()
{
return this.iterator();
}
public String toString()
{
LinearNode <T> current = head;
String result ="";
String line = "";
int loopCount=0;
while(current != null)
{
loopCount++;
line = loopCount + "> " + (String) current.getElement() + "\n";
result = result + line;
current = current.getNext();
}
return result;
}
}
Your problem
You're getting an overflow because the line this.iterator() in your function public Iterator<T> iterator(), calls, you guessed it public Iterator<T> iterator().
Approach 1: The lazy way
If you don't plan on using the iterator for this class, (this looks like a programming assignment) you can always do the super super lazy.
public Iterator<T> iterator() {
throw new UnsupportedOperationException("Pffffft you don't need no iterator");
}
This approach is listed here just for completeness. Seeing as your linked list has no other way to access a random element in the middle without removing everything in front or behind it, I recommend you:
DO NOT DO THIS
Approach 2: The Correct Way
The thing about iterators is that they do a specific subset of what a list does, namely hasNext(), next(), and remove(). If you're unsure what those three methods do, I suggest you take a look at http://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html
You should create a public inner class.
public class LinkedList<T> implements ListADT<T> {
... stuff
private class MyIterator<T> implements Iterator<T> {
//It's best practice to explicitly store the head in the iterator
private LinearNode<T> head;
public MyIterator<T>(LinkedList<T>) {
...
}
#Override
public boolean hasNext() {
...
}
#Override
public T next() {
...
}
#Override
public void remove() {
...
}
}
public Iterator<T> iterator() {
return new MyIterator<T>(this);
}
}
Now if you're really clever, you can rewrite the rest of your code based on the iterator. Note:
DO THIS