I have implemented a Queue using 2 Stacks in Java where I follow this algorithm:
enQueue(x)
Push x to stack1
deQueue()
1) If both stacks are empty then error.
2) If stack2 is empty while stack1 is not empty, push everything from stack1 to stack2.
3) Pop the element from stack2 and return it.
Now, the problem here is that the first deQueue() operation is very slow (since it transfers everything to stack2). Can we modify the algorithm somehow so that deQueue is O(1) always? Are there other alternatives?
You can swap the two stacks.
deQueue()
If both stacks are empty then error.
If stack2 is empty, while
stack1 is not empty, swap the two stacks.
Pop the element from
stack2 and return it.
Using a swap, the operation is always O(1)
If you need a FIFO queue, use two queues. Only use a stack if you need LIFO behaviour.
If this is the case, there is no difference between using one queue or two queues, so you may as well use just one queue. If you are using threads, use an ExecutorService which wraps a Queue and a thread pool.
I'll bite: Why not use a doubly linked list? This should be O(1) push and O(1) pop.
When we say first deQueue() operation is very slow (since it transfers everything to stack2).
I am assuming we are talking about this
2) If stack2 is empty while stack1 is not empty, push everything from
stack1 to stack2.
Are we simply transferring everything we have in stack1 to stack2, in same order. That will be simple assignment (stack2=stack1;) and hence O(1).
Alternatively, if we are saying we need to pop everything from stack1, one by one, and add to stack2. We are basically talking about reversing a list(stack1), and assigning to stack2 (assignment is O(1), we know). There are various good algorithms to reverse a list http://www.codeproject.com/Articles/27742/How-To-Reverse-a-Linked-List-3-Different-Ways.
If you are using Java(as per the tag), you could simple use Collections.reverse(arrayList); to reverse the list.
Related
I am using Queue<T> q1 and I know that an element will be added using q1.offer(); at the end of the queue. But now, what I want to do is add an element in front of queue, which is not possible with Queue. The possible methods I could think of are
Use of double ended queue and I can add the elements in front and at the end.
reverse the q1, add the element at the end of the queue and reverse again.
Now, as a non-programmer guy, I am not sure, how to code these methods; which one is more economical and easier to do.
Problems I faced in 1) is transform of existing Queue to Deque and vice versa; and in 2) How to use Collections.reverseOrder(); to reverse the existing Queue.
The following is the way to add elements to the first of queue using deque and asLifoQueue method in collections.this will arrange the elements in last in first out order...
public class Practice15 {
public static void main(String[] args) {
Deque<Integer> dd=new ArrayDeque<Integer>();
dd.offerFirst(123);
dd.offerFirst(258);
dd.offerFirst(125);
System.out.println(dd);
Queue<Integer> q1=Collections.asLifoQueue(dd);
System.out.println(q1);
}
}
If you have to insert an element at the front, a Queue is definitely not the solution. Go for a double ended queue.
If you use "Queue q1" - that is only a declaration of variable q1, while Queue itself is only an interface. Are you probably looking to work with some implementation of Queue?
Check out Java API: http://docs.oracle.com/javase/7/docs/api/java/util/Queue.html)
I need to make a class Persistent queue in which the function enqueue takes an element enqueues it to the current queue and return the new queue. How ever the original queue remains unchanged. Similarly the dequeue function removes the front element an returns the new queue but the original queue remains unchanged. This can of course be done in O(length of queue) but can i do it faster.??
You can use a linked list as queue (not LinkedList, but your own implementation).
To add a new element you only have to create a new instance of your queue class, set its start element to the copied queue's start element, and create a new end element.
Removing an element is similar, but set the end element of the new queue to the second to last element of the copied queue.
The queue class could look like this:
static class Node {
final Node next;
final Object o;
Node(Node next, Object o) {...}
}
final Node start, end;
private Queue(Node start, Node end) {...}
public Queue(Object o) {
start = end = new Node(null, o);
}
public Queue add(Object o) {
return new Queue(start, new Node(end, o));
}
public Queue remove() {
return new Queue(start, end.next);
}
The complexity of this queue's add and remove methods is O(1).
Please note that you can only iterate this queue in reverse order (i.e. newest elements first). Maybe you can come up with something that can be iterated the other way around or even in both directions.
I suggest to have a look to scala implementation. Comment at the top of the class describes the chosen approach (complexity : O(1)).
Queue is implemented as a pair of Lists, one containing the ''in'' elements and the other the ''out'' elements.
Elements are added to the ''in'' list and removed from the ''out'' list. When the ''out'' list runs dry, the
queue is pivoted by replacing the ''out'' list by ''in.reverse'', and ''in'' by ''Nil''.
Adding items to the queue always has cost O(1). Removing items has cost O(1), except in the case
where a pivot is required, in which case, a cost of O(n) is incurred, where n is the number of elements in the queue. When this happens,
n remove operations with O(1) cost are guaranteed. Removing an item is on average O(1).
http://xuwei-k.github.io/scala-library-sxr/scala-library-2.10.0/scala/collection/immutable/Queue.scala.html
What I do is use Java Chronicle (disclaimer: which I wrote). This is an unbounded off heap persisted queue which is stored on disk or tmpfs (shared memory).
In this approach your consumer keeps track of where it is up to in the queue, but no entry is actually removed (except in a daily or weekly maintenance cycle)
This avoids the need to alter the queue except when adding to it, and you would not need to copy it.
As such maintaining multiple references to where each consumer believes is the tail of the queue is O(1) for each consumer.
As Chronicle uses a compact binary form, the limit to how much you can store is limited by your disk space. e.g. a 2 TB drive can store this much data even on a machine with 8 GB before you have to rotate the queue logs.
It looks to me that there is no way to insert an element somewhere in the middle of a Deque class in O(1) time. I want to maintain a reference to a particular node in the deque in say a hash table and if I need to remove this node, I just go to its prev and set the prev.next=this.next and similarly this.next.prev=prev and remove this current elem.
But if I have a deque as
Deque<String> myDeque = new ArrayDeque<String>();
or
Deque<String> myDeque = new LinkedList<String>();
none of these would provide this.
Is there an alternative to this? If I have to implement my own Doubly linked list, is there a way that I can do away by just extending what ArrayDeque already does so I don't have to rewrite the code for insert etc? ...well as far as i know...i don't think so : ( : (
This is not possible without writing your own Deque. However:
If I understand correctly you want O(1) removal and insertion at one specific point in an object that otherwise has the interface of a Deque? May I suggest that you use two Deques?
Insertion and removal are at first only in one of the Deques, untill you come across the node you want to save. At that point, depending on wether you insert this node at the front or at the back you don't do that, but insert the node in the empty Deque, and that empty Deque becomes the target for either all your insertions and removals at the front or the back from then on, and the other Deque only handles insertions and removals at the back or front.
This would scale maybe to a few key nodes (leading to [number of nodes]+1 Deques used), with only insertions/removals happening at the front of one Deque and at the back of one other Deque (all others are static). You would also have to introduce a fixed convention of wether the first or the last item in each Deque (except the first or the last Deque) is a "key" node.
Of course if you have random insertion and removal at many points the question becomes: Why do you insist on a Deque?
I wouldn't remove the node. Instead when you take it from the Deque I would check your collection of elements to be removed/ignored and then discard it if required.
Is there an efficient method to remove a range - say the tail - of X elements from a List, e.g. LinkedList in Java?
It is obviously possible to remove the last elements one by one, which should result in O(X) level performance. At least for LinkedList instances it should be possible to have O(1) performance (by setting the references around the first element to be removed and setting the head/tail references). Unfortunately I don't see any method within List or LinkedList to remove the last elements all at once.
Currently I am thinking of replacing the list by using List.subList() but I'm not sure if that has equal performance. At least it would be more clear within the code, on the other hand I would loose the additional functionality that LinkedList provides.
I'm mainly using the List as a stack, for which LinkedList seems to be the best option, at least regarding semantics.
subList(list.size() - N, list.size()).clear() is the recommended way to remove the last N elements. Indeed, the Javadoc for subList specifically recommends this idiom:
This method eliminates the need for explicit range operations (of the sort that commonly exist for arrays). Any operation that expects a list can be used as a range operation by passing a subList view instead of a whole list. For example, the following idiom removes a range of elements from a list:
list.subList(from, to).clear();
Indeed, I suspect that this idiom might be more efficient (albeit by a constant factor) than calling removeLast() N times, just because once it finds the Nth-to-last node, it only needs to update a constant number of pointers in the linked list, rather than updating the pointers of each of the last N nodes one at a time.
Be aware that subList() returns a view of the original list, meaning:
Any modification done to the view will be reflected in the original list
The returned list is not a LinkedList - it's an inner implementation of List that's not serializable
Anyway, using either removeFirst() or removeLast() should be efficient enough, because popping the first or last element of a linked list in Java is an O(1) operation - internally, LinkedList holds pointers to both ends of the list and removing either one is as simple as moving a pointer one position.
For removing m elements at once, you're stuck with O(m) performance with a LinkedList, although strangely enough an ArrayList might be a better option, because removing elements at the end of an ArrayList is as simple as moving an index pointer (denoting the end of the array) one position to its left, and no garbage nodes are left dangling as is the case with a LinkedList. The best choice? try both approaches, profile them and let the numbers speak for themselves.
I want to know why we always use Sorting algorithm like (Insertion Sort or Merge Sort,...) just for lists and arrays? And why we do not use these algorithms for stack or queue?
Stacks and queues are abstract data types that have their own sense of order, i.e. LIFO (Last In First Out) for stacks and FIFO (First In First Out) for queues. As such, it does not make sense to take a queue/stack and reorder their elements around.
Wikipedia references
Stack (data structure)
Queue (data structure)
On Stack vs Vector
You may notice that in Java, java.util.Stackextendsjava.util.Vector, and since it makes sense to sort a Vector, perhaps it also makes sense to sort a Stack. This is not the case however; the fact that Stack extends Vector is in fact a design blunder. A stack is NOT a vector.
Related questions
Java Stack class inherit Vector Class
On using Collections.sort on java.util.Stack
Despite the fact that it doesn't make sense to use, say, quicksort on a stack, you CAN actually use Collections.sort on a java.util.Stack. Why? Because, by virtue of design error (this can't be emphasized enough!), a java.util.Stack is a java.util.Vector, which implements java.util.List, and you certainly can sort a List. Here's an example:
Stack<Integer> stack = new Stack<Integer>();
stack.push(1);
stack.push(3);
stack.push(5);
stack.push(2);
stack.push(4);
Collections.sort(stack); // by virtue of design error!!!
System.out.println(stack); // prints "[1, 2, 3, 4, 5]"
while (!stack.isEmpty()) {
System.out.println(stack.pop());
} // prints "5", "4", "3", "2", "1"
Note that the elements are printed in descending order: this is because of how java.util.Stack is implemented. It pushes to and pops from the end of the Vector. You don't need to know this; you shouldn't have known this; but these are the facts.
On using an appropriate data structure
Depending on what it is that you're trying to accomplish, a TreeSet may be the appropriate data structure. It is a Set, so it does not permit duplicate elements.
NavigableSet<Integer> nums = new TreeSet<Integer>();
nums.add(5);
nums.add(3);
nums.add(1);
nums.add(2);
nums.add(6);
System.out.println(nums.pollFirst()); // prints "1"
System.out.println(nums.pollFirst()); // prints "2"
nums.add(4);
System.out.println(nums.pollFirst()); // prints "3"
System.out.println(nums.pollFirst()); // prints "4"
That's because the order of a stack or a queue is part of the definition of these data structures. If we sorted them, they wouldn't be stacks or queues.
As others noted, in general it doesn't make sense to order stacks and queues. Just to make the picture full, there is an exception: PriorityQueue, which keeps its elements ordered.
A Stack or Queue are concepts which differ from Sequences. Arrays and Linked Lists represent Sequences, on which you can think of them as sorted or unsorted.
Stack and Queue have their own unique structure.
Stack is a structure that applies Last In First Out(LIFO). If you ordered a Stack, then it would violate LIFO.
Think that I add 7, 3, 5, 4 to a stack.
As you know, stack can only retrieve the last added element. Whenever, we call pop() method, it will retrieve 4.
However, think that you now sort it. It becomes 3, 4, 5, 7 and when we pop(), it will retrieve 7 which was the first element that we added. This violates LIFO rule.
The same is valid for Queue, because Queue structure applies First in First Out. If you have any question, please don't hesitate to ask.
First of all Stack and Queues are also list but having some special characteristics. Since they are list you can always sort them but if you do that you might alter properties of these data structures.
Then there will be no point to using these data structure throughout your code and at some point sort them to loose their property for which we were using them.