Best implementation of Java Queue? - java

I am working (in Java) on a recursive image processing algorithm that recursively traverses the pixels of the image, outwards from a center point.
Unfortunately, that causes a Stack Overflow. So I have decided to switch to a Queue-based algorithm.
Now, this is all fine and dandy- but considering the fact that its queue will be analyzing THOUSANDS of pixels in a very short amount of time, while constantly popping and pushing, WITHOUT maintaining a predictable state (It could be anywhere between length 100, and 20000), the queue implementation needs to have significantly fast popping and pushing abilities.
A linked list seems attractive due to its ability to push elements onto itself without rearranging anything else in the list, but in order for it to be fast enough, it would need easy access to both its head, AND its tail (or second-to-last node if it were not doubly-linked). Sadly, I cannot find any information related to the underlying implementation of linked lists in Java, so it's hard to say if a linked list is really the way to go...
This brings me to my question. What would be the best implementation of the Queue interface in Java for what I intend to do? (I do not wish to edit or even access anything other than the head and tail of the queue -- I do not wish to do any sort of rearranging, or anything. On the flip side, I DO intend to do a lot of pushing and popping, and the queue will be changing size quite a bit, so preallocating would be inefficient)

Use:
Queue<Object> queue = new LinkedList<>();
You can use .offer(E e) to append an element to the end of the queue and .poll() to dequeue and retrieve the head (first element) of the queue.
Java defined the interface Queue, the LinkedList provided an implementation.
It also maintains references to the Head and Tail elements, which you can get by .getFirst() and .getLast() respectively.
credit to #Snicolas for suggesting queue interface

If you use LinkedList be careful. If you use it like this:
LinkedList<String> queue = new LinkedList<String>();
then you can violate queue definition, because it is possible to remove other elements than first (there are such methods in LinkedList).
But if you use it like this:
Queue<String> queue = new LinkedList<String>();
it should be ok,as this is heads-up to users that insertions should occur only at the back and deletions only at the front.
You can overcome defective implementation of the Queue interface by extending the LinkedList class to a PureQueue class that throws UnsupportedOperationException of any of the offending methods. Or you can take approach with aggreagation by creating PureQueue with only one field which is type LinkedList object, list, and the only methods will be a default constructor, a copy constructor, isEmpty(), size(), add(E element), remove(), and element(). All those methods should be one-liners, as for example:
/**
* Retrieves and removes the head of this queue.
* The worstTime(n) is constant and averageTime(n) is constant.
*
* #return the head of this queue.
* #throws NoSuchElementException if this queue is empty.
*/
public E remove()
{
return list.removeFirst();
} // method remove()

Check out the Deque interface, which provides for insertions/removals at both ends. LinkedList implements that interface (as mentioned above), but for your use, an ArrayDeque may be better -- you won't incur the cost of constant object allocations for each node. Then again, it may not matter which implementation you use.
Normal polymoprhism goodness comes to play: the beauty of writing against the Deque interface, rather than any specific implementation of it, is that you can very easily switch implementations to test which one performs best. Just change the line with new in it, and the rest of the code stays the same.

It's better to use ArrayDeque instead of LinkedList when implementing Stack and Queue in Java. ArrayDeque is likely to be faster than Stack interface (while Stack is thread-safe) when used as a stack, and faster than LinkedList when used as a queue. Have a look at this link Use ArrayDeque instead of LinkedList or Stack.

If you know the upper bound of possible quantity of items in the queue, circular buffer is faster than LinkedList, as LinkedList creates an object (link) for each item in the queue.

I think you can some up with simple like implementation
package DataStructures;
public class Queue<T> {
private Node<T> root;
public Queue(T value) {
root = new Node<T>(value);
}
public void enque(T value) {
Node<T> node = new Node<T>(value);
node.setNext(root);
root = node;
}
public Node<T> deque() {
Node<T> node = root;
Node<T> previous = null;
while(node.next() != null) {
previous = node;
node = node.next();
}
node = previous.next();
previous.setNext(null);
return node;
}
static class Node<T> {
private T value;
private Node<T> next;
public Node (T value) {
this.value = value;
}
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public void setNext(Node<T> next) {
this.next = next;
}
public Node<T> next() {
return next;
}
}
}

However, if you still want to use the recursive algorithm, you can change it to be "tail-recursive" which probably is optimized in the JVM to avoid stack overflows.

O(1) access to first and last nodes.
class Queue {
private Node head;
private Node end;
public void enqueue(Integer data){
Node node = new Node(data);
if(this.end == null){
this.head = node;
this.end = this.head;
}
else {
this.end.setNext(node);
this.end = node;
}
}
public void dequeue (){
if (head == end){
end = null;
}
head = this.head.getNext();
}
#Override
public String toString() {
return head.getData().toString();
}
public String deepToString() {
StringBuilder res = new StringBuilder();
res.append(head.getData());
Node cur = head;
while (null != (cur = cur.getNext())){
res.append(" ");
res.append(cur.getData());
}
return res.toString();
}
}
class Node {
private Node next;
private Integer data;
Node(Integer i){
data = i;
}
public Integer getData() {
return data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}

Here is the Queue Implementation with Iterator and Iterable interface
Queue Size will increase as It gets full
Queue Interface
package com.practice.ds.queue;
import com.practice.ds.queue.exception.QueueException;
public interface QueueInterface<T> {
public boolean empty();
public void enqueue(T item);
public void dequeue() throws QueueException;
public T front() throws QueueException;
public void clear();
}
Custom Exception Class
package com.practice.ds.queue.exception;
public class QueueException extends Exception {
private static final long serialVersionUID = -884127093599336807L;
public QueueException() {
super();
}
public QueueException(String message) {
super(message);
}
public QueueException(Throwable e) {
super(e);
}
public QueueException(String message, Throwable e) {
super(message, e);
}
}
Implementation of Queue
package com.practice.ds.queue;
import java.util.Iterator;
import com.practice.ds.queue.exception.QueueException;
public class Queue<T> implements QueueInterface<T>, Iterable<T> {
private static final int DEFAULT_CAPACITY = 10;
private int current = 0;
private int rear = 0;
private T[] queueArray = null;
private int capacity = 0;
#SuppressWarnings("unchecked")
public Queue() {
capacity = DEFAULT_CAPACITY;
queueArray = (T[]) new Object[DEFAULT_CAPACITY];
rear = 0;
current = 0;
}
#Override
public boolean empty() {
return capacity == current;
}
#Override
public void enqueue(T item) {
if(full())
ensureCapacity();
queueArray[current] = item;
current++;
}
#Override
public void dequeue() throws QueueException {
T dequeuedItem = front();
rear++;
System.out.println("Dequed Item is " + dequeuedItem);
}
#Override
public T front() throws QueueException {
return queueArray[rear];
}
#Override
public void clear() {
for (int i = 0; i < capacity; i++)
queueArray[i] = null;
current = 0;
rear = 0;
}
#SuppressWarnings("unchecked")
private void ensureCapacity() {
if (rear != 0) {
copyElements(queueArray);
} else {
capacity *= 2;
T[] tempQueueArray = (T[]) new Object[capacity];
copyElements(tempQueueArray);
}
current -= rear;
rear = 0;
}
private void copyElements(T[] array) {
for (int i = rear; i < current; i++)
array[i - rear] = queueArray[i];
queueArray = array;
}
#Override
public Iterator<T> iterator() {
return new QueueItearator<T>();
}
public boolean full() {
return current == capacity;
}
private class QueueItearator<T> implements Iterator<T> {
private int index = rear;
#Override
public boolean hasNext() {
return index < current;
}
#SuppressWarnings("unchecked")
#Override
public T next() {
return (T) queueArray[index++];
}
}
}

Related

Java priority queue that extends comparable?

I am working on a class assignment and I don't quite understand how to use comparator in the way the assignment is asking.
The assignment reads:
"Complete the Priority Queue class
Your Priority Queue must use an anonymous function to decide priority
It must take the Function interface as a parameter to the constructor
You should still have the default constructor – and if no function is provide use the compareTo function of the class"
This is the class that I am working on...
public class PriorityQueue <Item extends Comparable<Item>> {
public PriorityQueue()
{
}
public PriorityQueue(Comparator<Item> compare )
{
}
private int size = 0;
private Node<Item> head = null;
private Comparator<Item> compare ;
private static class Node<Item>
{
private Item data;
private Node<Item> next;
public Node(Item data, Node<Item> next)
{
this.data = data;
this.next = next;
}
public Node(Item data)
{
this.data = data;
this.next = null;
}
public Node()
{
this.data = null;
this.next = null;
}
}
#Override
public int size() {
return size;
}
#Override
public Item dequeue() {
// TODO Auto-generated method stub
return null;
}
#Override
public void enqueue(Item item) {
Node<Item> curr = head;
Node<Item> prev = curr;
if (isEmpty())
{
head = new Node<Item>(item,null);
}
else
{
while (curr != null)
{
prev = curr;
curr = curr.next;
}
prev.next = new Node<Item>(item, curr);
}
size++;
}
#Override
public boolean isEmpty() {
return size == 0;
}
#Override
public void printQueue() {
Node<Item> curr = head;
while (curr != null)
{
System.out.println(curr.data);
curr = curr.next;
}
}
}
This is the process class that the queue will contain...
public class Process implements Comparable<Process> {
private ProcessPriorty priority;
private String name;
public Process(ProcessPriorty priority, String name) {
super();
this.priority = priority;
this.name = name;
}
public void setPriority(ProcessPriorty priority) {
this.priority = priority;
}
#Override
public String toString() {
return name + "... Priority = " + priority + ".";
}
public String getName() {
return name;
}
public ProcessPriorty getPriority() {
return priority;
}
#Override
public int compareTo(Process other) {
if(other == null)
{
return 1;
}
return this.priority.compareTo(other.priority) ;
}
}
I understand the concept of a queue and have even coded the enqueue method to work as a simple queue that inserts the items as they come in. The problem I am coming across is comparing the nodes within that method to sort the list by priority at insertion. Which I believe relates back to those three directions of the assignment. So, what am I suppose to do with the constructors, the Comparator variable, and how do I make it default to compareTo?
Well since you have a reference to the head of the queue, its pretty simple from there. You have 2 cases -
compare != null
compare == null
In the first case, you are interested in Comparator::compareTo. From the definition of a priority queue, all you have to do is traverse the queue beginning from head, and as soon as the item in enqueue(Item item) is greater than the current element in the traversal, you insert item before element. You'll use compare.compareTo(item, element) to determine their order.
In the second case you'll simply use item.compareTo(element) to make the above stated comparison, the traversal and insertion will be the same.

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);
}
}

Java single LinkedList add with O(1) complexity

I'm trying to understand LinkedLists(Single LinkedList to be precise).
I heard/read that delete and add operation will be performed with O(1) complexity and I'm still not getting how to implement with O(1) complexity for these two operation.
Below is my implementation in java(NOTE: I don't know c, c++ coding, So I recently started understanding data structures).
public class Node
{
private Integer data = null;
private Node next = null;
private int size = 0;
public Node()
{
}
private Node(Integer data)
{
this.data = data;
}
public boolean add(Integer data)
{
if (null == data) return false;
if (null == this.data)
{
this.data = data;
}
else
{
if (null == this.next)
{
this.next = new Node(data);
}
else
{
this.next.add(data);
}
}
size += 1;
return true;
}
public Integer getDataAt(int index)
{
if (index == 0)
{
return this.data;
}
else
{
return this.next.getDataAt(index - 1);
}
}
public int getSize()
{
return size;
}
}
Please suggest me to edit as of now add(data) to make it O(1) complexity.
Only Adding and Removing operation in LinkedList is O(1) but traversing to the node you want to remove or add is an O(N) operation
You can achieve the O(1) complexity if you keep the reference to your last added element so you can put add new Node to the last traversed element's next Node.
In linkedList if you have head and tail pointer to point first and last of node linkedlist then in constant time you can add and remove in first or last position of the node.If you want to delete an element you have to find that element and in worst case that element will be in last .In doubly linkedlist you can start from start and end so you have to traverse till so in worst case it will be O(n).
Thank you for all your support, as a NOOB in data structure I want to understand how ds workds rather than copy pasting from someone's else implementation.
Neeraj Jain & Gati Sahu's explanations/answer helped me to achieve what I'm looking for add(data) in LinkedList with O(1) complexity.
So what I did is "Segregate Plain Node class and create LinkedList class with operations.
class Node
{
private Integer data = null;
private Node next = null;
public Node(Integer data)
{
super();
this.data = data;
}
public Integer getData()
{
return data;
}
public Node getNext()
{
return next;
}
public void setData(Integer data)
{
this.data = data;
}
public void setNext(Node next)
{
this.next = next;
}
}
public class LinkedList
{
Node head;
Node end;
public Node getHead()
{
return head;
}
public boolean add(Integer data)
{
if (null == head)
{
head = new Node(data);
end = head;
}
else
{
addAtEnd(data);
}
return true;
}
public void addAtEnd(Integer data)
{
end.setNext(new Node(data));
end = end.getNext();
}
public void addAtFirst(Integer data)
{
Node tmpNode = head;
head = new Node(data);
head.setNext(tmpNode);
}
}

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!

Sorted Stack in 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.

Categories

Resources