Sorted Stack in Java - java

I'm trying to implement a stack that keeps the items in a sorted manner and returns the least element in every pop. I'm using two stacks to implement the sorted stack.
Here's my implementation of the plain vanilla stack.
public class Stack<T> implements Iterable{
private Node head;
#Override
public Iterator iterator() {
return new StackIterator();
}
private class Node<T extends Comparable<T>>{
private T data;
private Node next;
public Node(T data){
this.data = data;
next = null;
}
public int compareTo(T other){
return data.compareTo(other);
}
}
private class StackIterator<T> implements Iterator<T> {
Node current = head;
#Override
public boolean hasNext() {
return (current != null);
}
#Override
public T next() {
T item = (T) current.data;
current = current.next;
return item;
}
}
public void push(T item){
Node p = new Node((Comparable) item);
if(head == null){
head = p;
return;
}
p.next = head;
head = p;
}
public T pop(){
if(head == null){
System.out.println("Popping off an empty stack!!!");
System.exit(-1);
}
T item = (T) head.data;
head = head.next;
return item;
}
}
This stack is used in the SortedStack. Here's the partial code.
public class SortedStack<T> {
private int size;
private Stack<T> s1;
private Stack<T> s2;
public SortedStack(){
s1 = new Stack<>();
s1 = new Stack<>();
size = 0;
}
public void push(T item){
for (Iterator<T> iter = s1.iterator(); iter.hasNext(); iter.next()){
if (iter.compareTo(item) > 0){
s2.push(s1.pop());
}else if(iter.compareTo(item) < 0){
s1.push(item);
break;
}else{
s1.push(item);
break;
}
}
for (Iterator<T> iter = s2.iterator(); iter.hasNext(); iter.next()){
s1.push(s2.pop());
}
}
public T pop(){
}
}
The problem is the T(Object) comparison of the nodes doesn't get resolved in the SortedStack. The compareTo doesn't work. This is understandably because of the fact that Node is an inner private class of Stack. My question is how can I expose the compareTo method of the Node class to the SortedStack for implementing it's logic without indiscriminately making everything public?

You have many mistakes in your code.
For example, why are you trying to compare an iterator to an item?
Also, the logic is broken: you compare an item being inserted to s1's head, and then push it to the tail.
As long as the first item inserted is the smallest of all, all the others will always end up in the insertion order.
Consider inserting 0, then 3, then 1 for example.
To answer your question, you want your extends Comparable<T> type boundary on the SortedStack declaration, not on Node.
Node does not need to be Comparable at all.
If this is not for homework, just use TreeSet instead.

Related

How can I change my Iterator to be a Fast-fail Iterator?

I'm trying to understand how to modify the Iterator of my Linked List to be fail-fast.
I understand what it means for an Iterator to be fail-fast, but I don't know how exactly should I change my implementation to achieve this behavior.
I was thinking about adding a key so for every add, but I don't think it is good enough. It is the first time I'm trying to implement a fail-fast iterator, and I would really appreciate any hint.
My code:
package GenericLinkedList;
import java.util.Iterator;
public class GenericLinkedList<E> implements Iterable<E> {
private Node<E> head;
public void pushFront(E data){
head = new Node<>(data, head);
}
public E popFront(){
E dataHead = head.data;
head = head.next;
return dataHead;
}
public int size(){
int counter = 0;
for(E element : this){
++counter;
}
return counter;
}
public boolean isEmpty(){
return (null == head);
}
public Iterator<E> find(E data){
IteratorIMP iter = new IteratorIMP(head);
for(E element : this){
if(element.equals(data)){
return iter;
}
iter.next();
}
return null;
}
public static <E> GenericLinkedList<E> merge(GenericLinkedList<E> firstList, GenericLinkedList<E> secondList){
GenericLinkedList<E> mergeList = new GenericLinkedList<E>();
for(E element : firstList){
mergeList.pushFront(element);
}
for(E element : secondList){
mergeList.pushFront(element);
}
return newReverse(mergeList);
}
public static <E> GenericLinkedList<E> newReverse(GenericLinkedList<E> list){
GenericLinkedList<E> reverseList = new GenericLinkedList<E>();
for(E element : list){
reverseList.pushFront(element);
}
return reverseList;
}
private static class Node<T> {
private Node<T> next;
private T data;
private Node(T data, Node<T> next) {
this.data = data;
this.next = next;
}
}
private class IteratorIMP implements Iterator<E> {
Node<E> node;
private IteratorIMP(Node<E> start){
node = start;
}
#Override
public boolean hasNext() {
return (node != null);
}
#Override
public E next() {
E data = node.data;
node = node.next;
return data;
}
}
#Override
public Iterator<E> iterator() {
IteratorIMP iter = new IteratorIMP(head);
return iter;
}
}
Fail-fast implementation of the Iterator insures that it would raise an exception if there's an evidence that the collection is being structurally modified (an element was added or removed) during the iteration process, because in such a case, iterator might not be able to reflect the actual state of the collection.
The common approach is to introduce two counters of modifications:
one as the instance field of the list modCount, which would be incremented whenever list gets modified via pushFront(), popFront(), etc.
another in the Iterator - expectedModCount.
If during the next() call turns out that modCount and expectedModCount variables are not equal, that means that there has been a modification after the iterator was created. In such a case, fail-fast Iterators from the JDK would throw ConcurrentModificationException.
public class GenericLinkedList<E> implements Iterable<E> {
private Node<E> head;
private int modCount;
public void pushFront(E data) {
modCount++; // list is being modified - incrementing the count
head = new Node<>(data, head);
}
public E popFront() {
modCount++; // list is being modified - incrementing the count
E dataHead = head.data;
head = head.next;
return dataHead;
}
// ...
private class IteratorIMP implements Iterator<E> {
private Node<E> node;
private final int expectedModCount;
private IteratorIMP(Node<E> start) {
this.node = start;
this.expectedModCount = GenericLinkedList.this.modCount;
}
// ...
#Override
public E next() {
if (expectedModCount != modCount) {
throw new ConcurrentModificationException();
}
E data = node.data;
node = node.next;
return data;
}
}
}

Overriding the compareTo method with a class that is nested inside another class which extends Comparable

I am tasked with writing my own PriorityQueue class in Java. It is based on LinkedLists. To quote the directions:
The type of the data stored in the nodes should be a generic type that is comparable. That is write for the class declaration: public class PriorityQueue (E extends Comparable)) -> note: the curly braces are meant to mean <>, whatever I write between <> is disappearing...
I will be using the PriorityQueue to write two other classes, one of type patient, the other of waitingRoom. This is where the compareTo method will come into play, as I sort the two classes into their individual PriorityQueues.
I have been defining the ListNode class inside of the PriorityQueue class itself, so I have a class within a class. Now comes the question:
Where am I going to implement/Override the inherited compareTo method from Comparable?
It can't get implemented in the PriorityQueue class because compareTo can only take one argument. Yet, this is where it seems like it should go, as this is the actual class extending Comparable.
If I implement it inside the ListNode class, well, I have no idea how I would. Do I turn ListNode into an interface? An AbstractClass?
Below is the quite novice code I have written, thanks for the help
package hostpitalQueue;
import java.util.AbstractList;
public class PriorityQueue<E extends Comparable<E>> {
private ListNode front;
public PriorityQueue() {
front = null;
}
public PriorityQueue(ListNode n1) {
front = n1;
}
//method for addingNode to beginning,
//perhaps overload method for next nodes?
public void addNode(ListNode n1) {
if(front == null) {
front = n1;
}else {
//need to find last node and add n1 to it
ListNode lastNode = findLastNode(n1);
lastNode.addNode(n1);
}
}
//need to compare, remember, this is a priorityqueue
public ListNode findLastNode(ListNode n) {
//compare the data of both
//compare to front
ListNode n1 = front;
int i = n1.compareTo(n);
//only do something here if n is higher priority
if(i > 0) {
E frontData = n1.data;
E nodesData = n.data;
ListNode holder = n1;
front = n;
n.next = holder;
holder.previous = n;
}else if(n1.next == null) {
n1.next = n;
n.previous = n1;
}
else {
while(front.next != null) {
n1 = front.next;
//is n1 a higher priority?
Integer ii = n1.compareTo(n);
if(ii > 0) {
//this means that we should return the previous node, to insert
//before this one
return n1.previous;
}
}
}
return n1;
}
public class ListNode {
//contains a left and a right, as well as a data field
public E data;
public ListNode previous,next;
//construct
public ListNode() {
data = null;
previous = null;
next = null;
}
//previous to next
public ListNode(E data) {
this.data = data;
previous = null;
next = null;
}
public ListNode(E data,ListNode n1) {
this.data = data;
previous = n1;
next = null;
}
public ListNode(E data,ListNode n1,ListNode n2) {
this.data = data;
previous = n1;
next = n2;
}
public void addNode(ListNode n1) {
//gotta check if my next is null
ListNode holder = null;
if(this.next != null) {
holder = this.next;
}
this.next = n1;
n1.previous = this;
n1.next = holder;
}
public int compareTo(ListNode n1) {
return 0;
}
public void printMe() {
System.out.println(this.data);
}
}
}
Each class that you will use as element type of PriorityQueue must implement the Comparable interface and the compareTo method.
Note that as your ListNode class implements a compareTo method, you could have made it implement Comparable<ListNode>:
public class ListNode implements Comparable<ListNode> {
...
#Override
public int compareTo(ListNode n1) {
return data.compareTo(n1.data);
}
Note that as you ListNode classe doesn't depend on an instance of PriorityQueue, you could have made it static; in which case, you would have had to declare a generic argument:
public static class ListNode<T extends Comparable<T>>
implements Comparable<ListNode<T>> {
//contains a left and a right, as well as a data field
public T data;
public ListNode<T> previous,next;
//construct
public ListNode() {
data = null;
previous = null;
next = null;
}
//previous to next
public ListNode(T data) {
this.data = data;
previous = null;
next = null;
}
public ListNode(T data,ListNode<T> n1) {
this.data = data;
previous = n1;
next = null;
}
public ListNode(T data,ListNode<T> n1,ListNode<T> n2) {
this.data = data;
previous = n1;
next = n2;
}
public void addNode(ListNode<T> n1) {
//gotta check if my next is null
ListNode<T> holder = null;
if(this.next != null) {
holder = this.next;
}
this.next = n1;
n1.previous = this;
n1.next = holder;
}
#Override
public int compareTo(ListNode<T> n1) {
return data.compareTo(n1.data);
}
public void printMe() {
System.out.println(this.data);
}
}
class ListNode has fields, so you can't change it to an interface (why the hell would you do that anyway?)
You should perhaps ask yourself if you really need a doubly linked list and if a singly linked list would not suffice.
It is unclear in your question if you need to implement a linked list or if you could make use of the class LinkedList in which case you would not need the ListNode class: PriorityQueue would just encapsulate a LinkedList<E>.
If you are wanting to compare two ListNodes, as in the line:
n1.compareTo(n)
You'd need to make it implement Comparable:
public class ListNode implements Comparable<ListNode> {
And implement the compareTo method as something like:
return this.data.compareTo(that.data);
(since you know the data is Comparable). But you would have to handle the case of null data.
Note that you should also declare your type variable on the top-level class as:
<E extends Comparable<? super E>>

Adding nodes to a list in ascending order with Java

Is there a way to use the compareTo function when comparing objects, I'm not sure if it's just for Strings. I am trying add an node into its correct position in ascending order.
heres where I declare my attributes/constructor
private Node<E> head; //refers to the head of the node
private int size; // keeps track of the size of the list
// default constructor which creates empty ordered list
public OrderedList(){head = null; size = 0;}
Heres my insert function
public void insert(Object o)
{
Node n = new Node(o, null); // creates new node
// Node for first element greater than or equal
Node current = head.getLink();
Node before = head; // Node for right before the next one is found
// checks to see if list is empty
if(size == 0)
{
head = n;
}
// checks if element is smaller than the head
else if (o.compareTo(head.o) < 0)
{
n.getLink() = head;
head = n;
}
}
here is my node class
package project.pkg3;
public class Node<T>
{
private Object data;
private Node link;
public Node(Object o, Node l){data = o; link = l;}
public void setData(Object o){data = o;}
public void setLink(Node l){link = l;}
public Object getData(){return data;}
public Node getLink(){return link;}
}
I'm getting an error message when trying to check whether the element belongs in the front on this line
else if (o.compareTo(head.o) < 0)
telling me that it cannot find the symbol, which I'm not sure what that means
Im also getting another error message on this line
n.getLink() = head;
this one is telling me that it's an unexpected type
If your linked list must be sorted using compareTo(), then you need to make sure that the underlying data is comparable.
public class Node<T extends Comparable>
{
private T data;
private Node<T> link;
public Node(T o, Node<T> l) { data = o; link = l; }
public void setData(T o) { data = o; }
public void setLink(Node<T> l) {link = l; }
public T getData() { return data; }
public Node<T> getLink() { return link; }
}
Then this block
else if (o.compareTo(head.o) < 0)
{
n.getLink() = head;
head = n;
}
should be changed into this:
else if (
(o.getData() != null) ?
(o.getData().compareTo(head.getData()) < 0) :
(head.getData().compareTo(o.getData()) > 0)
)
{
n.setLink(head);
head = n;
}
I didn't look at your linked list implementation though, so I have no idea the other stuff are correct.
Your node class should implement java.lang.Comparable interface and override its compareTo() method as per your logic.
public class Node<T extends Comparable<T>>{
}
Your argument object would implement Comparable interface. For eg:
public class Name implements Comparable<Name> {
private String str1;
public int compareTo(Name o) {
//your logic here to compare object with itself
return this.str1.compareTo(o.str1);
}
}

Adding an element to a singly linked list in Java

I'm implementing a singly linked list in Java. What I don't like about this code is that I need to check if (head.next == null) every time I add an element. But the condition is met only once, when adding the first element.
Is there a way to implement a singly linked non-circular list without such a condition?
package sample;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class SinglyLinkedList<T> implements Iterable<T> {
private Node<T> head = new Node<T>(null);
private Node<T> last = null;
public SinglyLinkedList(T... elements) {
addAll(elements);
}
public void add(T element) {
if (head.next == null) {
head.next = new Node<T>(element);
last = head.next;
} else {
Node<T> newNode = new Node<T>(element);
last.next = newNode;
last = last.next;
}
}
public void addAll(T... elements) {
for (T element : elements) {
add(element);
}
}
#Override
public String toString() {
Iterator<T> iterator = iterator();
if (!iterator.hasNext()) {
return "[]";
}
StringBuilder builder = new StringBuilder();
builder.append("[");
while (iterator.hasNext()) {
T element = iterator.next();
builder.append(element);
if (!iterator.hasNext()) {
return builder.append("]").toString();
}
builder.append(", ");
}
return builder.toString();
}
#Override
public Iterator<T> iterator() {
return new Iterator<T>() {
Node<T> current = head;
#Override
public boolean hasNext() {
return current.next != null;
}
#Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
Node<T> temp = current;
current = current.next;
return temp.next.element;
}
};
}
private static class Node<T> {
private Node<T> next;
private T element;
Node(T element) {
this.element = element;
}
#Override
public String toString() {
return element.toString();
}
}
}
You could initialize last to be pointing to head and then your if is redundant:
private Node<T> head = new Node<T>(null);
private Node<T> last = head;
public void add(T element) {
Node<T> newNode = new Node<T>(element);
last.next = newNode;
last = last.next;
}
There are many cases where "good OO design" allows you to go without if/else checks; most often by using some form of polymorphism.
Meaning: instead of asking some object about some property, to then make a decision on that in your client code, you somehow make sure that your client code can simply call a method on some other object. And then, the "if" is "hidden" within the code that initially generated that "other object" and gave it to your client code. (you find some nice examples how that works in these videos).
But - I think this would be clear overkill in this case!
The point is: from a readability point of view, that one check really doesn't hurt (you could refactor things into more methods maybe). And performance ... doesn't matter either. If your code is called so often that it would matter, the JIT will kick in anyway, and probably create code that that takes the correct branch directly for most cases.
Thus: this is a nice implementation; and I think you shouldn't worry about this one if-check there!

Copying Linked List Recursively (Java)

End of a long night and I'm having trouble with copying a linked list recursively, I was able to do so with a simple iterative method, but I am having trouble with a stack overflow error when I try to set it up with recursion. Yet, this makes sense to me conceptually. Can anyone steer me in the right direction? This is what I have so far:
public LinkedList<E> createCopyRecursive(Node<E> aNode) {
LinkedList<E> copyList = new LinkedList<E>();
copyList.myStart = myStart;
if (copyList.size() == 0) {
aNode = myStart.getLink();
}
if (aNode.getLink() == null) {
return copyList;
}
else {
copyList.add(aNode.getValue());
return createCopyRecursive(aNode.getLink());
}
}
You're creating a new LinkedList every time you recurse into the method.
I suspect you want to instantiate it outside the method, pass it in and add to it each time through.
I think it can be as simple as this:
private LinkedList<E> copyRecursive(final Node<E> node, final LinkedList<E> accumulator) {
if (node == null) {
// all nodes traversed, return the result.
return accumulator;
}
// add current node to the copy list that is under construction.
accumulator.add(node.getElement());
// recursive call to copy the rest of the nodes to the copy list and return it when finished.
return copyRecursive(node.getNext(), accumulator);
}
First create an empty new linked list, which will contain the copy and then copy node by node into it recursively. You could also not pass an accumulator to it like this:
private LinkedList<E> copyRecursive(final Node<E> node) {
if (node == null) {
return new LinkedList<>();
}
final LinkedList<E> accumulator = copyRecursive(node.getNext());
accumulator.add(node.getElement());
return accumulator;
}
But that will reverse the order of the nodes in the list.
Here is a fully working example with recursive copy and recursive reverse:
public class RecursiveCopyTest {
public static void main(String[] args) {
final LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("first");
linkedList.add("next");
linkedList.add("last");
System.out.println(linkedList);
System.out.println(linkedList.copyRecursive());
System.out.println(linkedList.reverse());
}
private static class LinkedList<E> {
private Node<E> first;
public LinkedList() {
first = null;
}
public LinkedList<E> copyRecursive() {
return copyRecursive(first, new LinkedList<E>());
}
public LinkedList<E> reverse() {
return reverse(first);
}
public void add(E element) {
final Node<E> node = new Node<>(element);
if (first == null) {
first = node;
} else {
Node<E> current = first;
while (current.getNext() != null) {
current = current.getNext();
}
current.setNext(node);
}
}
private LinkedList<E> reverse(final Node<E> node) {
if (node == null) {
return new LinkedList<>();
}
final LinkedList<E> accumulator = reverse(node.getNext());
accumulator.add(node.getElement());
return accumulator;
}
private LinkedList<E> copyRecursive(final Node<E> node, final LinkedList<E> accumulator) {
if (node == null) {
return accumulator;
}
accumulator.add(node.getElement());
return copyRecursive(node.getNext(), accumulator);
}
#Override
public String toString() {
final StringBuilder stringBuilder = new StringBuilder();
Node current = first;
while (current != null) {
stringBuilder.append(current.getElement().toString()).
append(" -> ");
current = current.getNext();
}
stringBuilder.append(" _ ");
return stringBuilder.toString();
}
private static final class Node<E> {
private final E element;
private Node<E> next;
public Node(final E element) {
this.element = element;
}
public E getElement() {
return element;
}
public void setNext(final Node<E> next) {
this.next = next;
}
public Node<E> getNext() {
return next;
}
}
}
}
If you want to use a recursive method to copy your linked list, I think you should first initialize copyList in another mehod that calls createCopyRecursive().
createCopy(Node<E> aNode) {
LinkedList<E> copyList = new LinkedList<E>();
createCopyRecursive(aNode, copyList) {
....
}
}
Rather than passing around whole linkedlist object you can just worry about head node.
Call to recursive method copy()
Node<Integer> copiedHead = copy(head);
Recursive method copy, accepts the head node and returns the copied head node.
private static Node<Integer> copy(Node<Integer> head) {
if(head == null){
return null;
}
return new Node<>(head.getData(), copy(head.getNext()));
}

Categories

Resources