I need to create a method which sorts an array of integers using a Stack and a Queue. For instance if given [-1, 7, 0, 3, -2] -> [-2, -1, 0, 3, 7]. I'm completely lost at how to do this question, because I would just use a sorting method, however for this question I am not allowed to do that. Can anyone explain how to do this with a Stack and a Queue?

- 362,284
- 104
- 897
- 1,065

- 1,685
- 4
- 29
- 53
-
1It's not that you have to sort with a stack or a queue. It's possibly that, your array should be implemented as a stack or a queue. – Rohit Jain Jun 21 '13 at 19:41
-
Well given the requirement of using either a stack or a queue, the only logical way to do it would be to use some form of mergesort. – scott_fakename Jun 21 '13 at 19:45
-
1possible duplicate of [IBM interview question : how to sort a stack?](http://stackoverflow.com/questions/4826311/ibm-interview-question-how-to-sort-a-stack) – Philipp Jun 21 '13 at 19:45
-
Yes. First that you need it's transfer your data structure to array. Later you can use some of sort algorithm. Quick sort for example. – Petr Shypila Jun 21 '13 at 19:46
-
1Or maybe use [StackSort](http://gkoberger.github.io/stacksort/)? ... never mind, you are already doing that. – Philipp Jun 21 '13 at 19:46
-
sounds a bit like a homework request for a data stuctures course – Akunosh Jun 21 '13 at 20:00
-
Take a look at http://stackoverflow.com/a/23695092/3315914 – rpax Oct 01 '16 at 15:19
4 Answers
Many fast sorting algorithms (for example mergesort and quicksort) can be implemented efficiently on linked lists by using the fact that you can efficiently treat a singly-linked list as a stack (by prepending elements to the front) or queue (by appending elements to the back). Consequently, one possible way to solve this problem would be to take one of those sorting algorithms and approach it as if you were sorting a linked list rather than a normal sequence.
For example, here is one simple way that you could implement mergesort using queues. I've written this to sort Integer
s, but this could easily be extended to handle other types:
public void mergesort(Queue<Integer> sequence) {
/* Base case: Any 0- or 1-element sequence is trivially sorted. */
if (sequence.size() <= 1) return;
/* Otherwise, split the sequence in half. */
Queue<Integer> left = new LinkedList<Integer>(),
right = new LinkedList<Integer>();
while (!sequence.isEmpty()) {
left.add(sequence.remove());
if (!sequence.isEmpty()) {
right.add(sequence.remove());
}
}
/* Recursively sort both halves. */
mergesort(left);
mergesort(right);
/* Merge them back together. */
merge(left, right, sequence);
}
private void merge(Queue<Integer> one, Queue<Integer> two,
Queue<Integer> result) {
/* Keep choosing the smaller element. */
while (!one.isEmpty() && !two.isEmpty()) {
if (one.peek() < two.peek()) {
result.add(one.remove());
} else {
result.add(two.remove());
}
}
/* Add all elements from the second queue to the result. */
while (!one.isEmpty()) {
result.add(one.remove());
}
while (!two.isEmpty()) {
result.add(two.remove());
}
}
Overall, this will run in O(n log n) time, which is asymptotically optimal.
Alternatively, you could use quicksort, as shown here:
public void quicksort(Queue<Integer> sequence) {
/* Base case: Any 0- or 1-element sequence is trivially sorted. */
if (sequence.size() <= 1) return;
/* Choose the first element as the pivot (causes O(n^2) worst-case behavior,
* but for now should work out fine. Then, split the list into three groups,
* one of elements smaller than the pivot, one of elements equal to the
* pivot, and one of elements greater than the pivot.
*/
Queue<Integer> pivot = new LinkedList<Integer>(),
less = new LinkedList<Integer>(),
more = new LinkedList<Integer>();
/* Place the pivot into its list. */
pivot.add(sequence.remove());
/* Distribute elements into the queues. */
while (!sequence.isEmpty()) {
Integer elem = sequence.remove();
if (elem < pivot.peek()) less.add(elem);
else if (elem > pivot.peek()) more.add(elem);
else pivot.add(elem);
}
/* Sort the less and greater groups. */
quicksort(less);
quicksort(more);
/* Combine everything back together by writing out the smaller
* elements, then the equal elements, then the greater elements.
*/
while (!less.isEmpty()) result.add(less.remove());
while (!pivot.isEmpty()) result.add(pivot.remove());
while (!more.isEmpty()) result.add(more.remove());
}
This runs in best-case O(n log n) time and worst-case O(n2) time. For an interesting exercise, try making it pick the pivot at random to get expected O(n log n) runtime. :-)
For an entirely different approach, you could consider doing a least-significant digit radix sort on the values, since you know that they're all integers:
public void radixSort(Queue<Integer> sequence) {
/* Make queues for values with a 0 in the current position and values with a
* 1 in the current position. It's an optimization to put these out here;
* they honestly could be declared inside the loop below.
*/
Queue<Integer> zero = new LinkedList<Integer>(),
one = new LinkedList<Integer>();
/* We're going to need 32 rounds of this, since there are 32 bits in each
* integer.
*/
for (int i = 0; i < 32; i++) {
/* Distribute all elements from the input queue into the zero and one
* queue based on their bits.
*/
while (!sequence.isEmpty()) {
Integer curr = sequence.remove();
/* Determine whether the current bit of the number is 0 or 1 and
* place the element into the appropriate queue.
*/
if ((curr >>> i) % 2 == 0) {
zero.add(curr);
} else {
one.add(curr);
}
}
/* Combine the elements from the queues back together. As a quick
* note - if this is the 31st bit, we want to put back the 1 elements
* BEFORE the 0 elements, since the sign bit is reversed.
*/
if (i == 31) {
Queue<Integer> temp = zero;
zero = one;
one = temp;
}
while (!zero.isEmpty()) result.add(zero.remove());
while (!one.isEmpty()) result.add(one.remove());
}
}
This will run in time O(n log U), where U is the maximum possible value that can be stored in an int
.
Of course, all of these algorithms are efficient and elegant. Sometimes, though, you will want to do a slow and inelegant sort like bogosort. Now, bogosort is somewhat difficult to implement, since it typically requires you to shuffle the input sequence, which is way easier to do on an array. However, we can simulate shuffling a queue as follows:
- Choose a random index into the queue.
- Cycle through that many elements.
- Remove that element from the queue and add it to the result.
- Repeat.
This ends up taking time O(n2) rather than O(n), which has the unfortunate side-effect of making bogosort take expected time O(n2 &mdot; n!) rather than O(n &mdot; n!). However, it's the price we have to pay.
public void bogosort(Queue<Integer> sequence, Random r) {
while (!isSorted(sequence)) {
permute(sequence, r);
}
}
/* Checking if a sequence is sorted is tricky because we have to destructively modify
* the queue. Our process will be to cycle the elements of the sequence making sure
* that each element is greater than or equal to the previous element.
*
* Because we are using bogosort, it's totally fine for us to destructively modify
* the queue as long as all elements that were in the original input queue end up
* in the resulting queue. We'll do this by cycling forward through the elements
* and stopping if we find something mismatched.
*/
private void isSorted(Queue<Integer> sequence) {
int last = Integer.MIN_VALUE;
for (int i = 0; i < sequence.size(); i++) {
int curr = sequence.remove();
sequence.add(curr);
if (curr < last) return false;
}
return true;
}
/* Randomly permutes the elements of the given queue. */
private void permute(Queue<Integer> sequence, Random r) {
/* Buffer queue to hold the result. */
Queue<Integer> result = new LinkedList<Integer>();
/* Continuously pick a random element and add it. */
while (!sequence.isEmpty()) {
/* Choose a random index and cycle forward that many times. */
int index = r.nextInt(sequence.size());
for (int i = 0; i < index; i++) {
sequence.add(sequence.remove());
}
/* Add the front element to the result. */
result.add(sequence.remove());
}
/* Transfer the permutation back into the sequence. */
while (!result.isEmpty()) sequence.add(result.remove());
}
Hope this helps!

- 1
- 1

- 362,284
- 104
- 897
- 1,065
-
@templatetypedef Hey short question, let's say I wanted the parameter to be ArrayQueue
instead of Queue – QWERTY Jun 18 '15 at 01:24, how should I modify the answer?
You can implement a Selection sort fairly easily with a Stack and Queue:
If the data is originally on the stack, put it all on the Queue, and do the following:
int size = list.length; // list is the int[] sent as a method parameter.
while (size > 0) { // until we've placed all elements in their sorted positions
int min = Integer.MAX_VALUE; // make sure the minimum is bigger than all the data
for (int i = 0; i < size; i++) { // check all elements in the queue
int temp = queue.dequeue(); // mark the current element
if (temp < min) min = temp; // if it's a possible minimum record it.
queue.enqueue(temp); // place it back in the queue so we don't lose data.
}
for (int i = 0; i < size; i++) { // go through and remove the minimum element
int temp = queue.dequeue(); // mark the currently removed element
if (temp == min) break; // if it's the minimum, stop we've removed it.
queue.enqueue(temp); // otherwise put it back on.
}
stack.push(min); // put the minimum value on the stack (in sorted order)
size--; // we have one less element to consider, so decrement the size.
}
After the sort is over the elements will be sorted on the Stack, removing them all will return data in order Greatest to Least (which can easily be reversed).
No this is not very efficient, i'm assuming it's a homework assignment. Realisticaly if you want to sort data you should use Arrays.sort or Collections.sort which implement a merge sort for objects and a quicksort for primitives. These will be far faster (O(NlogN) vs O(N*N)). Realize however you'll need to have data in an array or a list to do this, not a stack or queue.

- 892
- 7
- 9
-
The method is supposed to take in an int[] list, which contains all the numbers. And then uses a Stack and Queue to sort it, which is unnecessary and pointless... EDIT: Also, I'm only limited to enqueue(), dequeue() and isEmpty() methods for the Queue, and push(), pop() and isEmpty() in the Stack. – Matthew Brzezinski Jun 21 '13 at 19:59
-
In that case simply put every element from the int[] onto the Queue, then at the end put all the elements from the stack into the int[] in reverse order. I'll edit the code for your methods. – Robert Mitchell Jun 21 '13 at 20:00
To simply sort the array
you can use Arrays.sort()
.
For queue specifically, PriorityQueue
is what you need to sort the Queue
. Have a look at the java docs.
You can insert the values in the PriorityQueue
using the add()
method and you will get a sorted Queue
back. You can also control the sorting order by using a Comparator
.

- 7,761
- 2
- 29
- 53
-
Isn't the question about how to use stacks and queues to sort a list? Priority queues and queues are not the same as queues, and `Arrays.sort` isn't an option for a stack or queue. – templatetypedef Jun 21 '13 at 19:54
-
When a question is tagged in java and is talking about `Queues`. Which `Queue` do you think the questioner is talking about. – JHS Jun 21 '13 at 19:56
-
I thought that the question was about stacks and queues in the abstract, not the Java `Stack` or `Queue` type. The question seems like a silly trick question if the answer is "in Java, these are actually implemented as arrays, so you can use standard sorting techniques." – templatetypedef Jun 21 '13 at 19:57
-
Exactly, thats why I gave the `Arrays.sort()` method and the `PriorityQueue` option. Let the questioner choose. – JHS Jun 21 '13 at 19:58
Stacks and Queues are data structures. Stack is a FILO and a Queue is FIFO. If you understand how those data structures work, you will be able to figure this out. Ultimately you can use the same logic that you would normally use for this type of problem, except you need to use stacks and queues as you data structures.
One way to use a stack in Java would be to sort the numbers with a recursive method, since Java has an internal memory stack.
Hope that helps.

- 23,275
- 22
- 95
- 156