3

I have a Stack variable (java collection) which holds five integers and I was also given one int variable. Is it possible to sort the numbers in the given stack. I am not able to solve that. Please post here if you have ideas.

Stack<Integer> s = new Stack<Integer>();
s.push(5);s.push(3);s.push(4);s.push(1);s.push(1);
int a;

We should not create any new variable except the one given in the above code snippet and also should not use Collections.sort(s).

6
  • Stack is a LIFO (Last In First Out) system. Why you want to sort the Stack items. It may break it's default (LIFO) behavior. You may consider to store the int item to another collection - like ArrayList then sort them. And keep th Stack intact. Commented Jun 6, 2015 at 6:55
  • I have been asked above programme in the interview which i was not able to solve.Please let me know if you have any idea . Commented Jun 6, 2015 at 7:00
  • 1
    Are you allowed to just call Collections.sort(s);? Commented Jun 6, 2015 at 7:09
  • 1
    @immibis,No, we can use it,but the interviewer asked me to no to use that. Commented Jun 6, 2015 at 7:21
  • 1
    If you detail more requirements in comments, please update tour questions with those reqs. Commented Jun 6, 2015 at 8:33

5 Answers 5

2

Terribly inefficient, but respects the rules :)

Stack<Integer> s=new Stack<Integer>();
s.push(5);s.push(3);s.push(4);s.push(1);s.push(1);

int a = -1;
while (a == -1) { // Here 'a' is used as a kind of boolean that tells us whether we need to keep checking for items to reorder or not.
    for (a = 0; a < s.size() - 1; a++) { // Now 'a' becomes stack element's index.
        if (s.get(a) > s.get(a + 1)) {
            a = s.remove(a); // Here 'a' again changes meaning and holds the value that needs to be reordered.
            s.push(a);
            a = -1; // And here, 'a' is back to being used as a kind of boolean flag to control the outer loop.
            break;
        }
    }
}

EDIT: Basically, I take advantage of the fact that I know that Stack extends Vector. So I don't actually have to use only the standard Pop and Push methods to access/remove elements. I can use normal List methods.

And then, I just squeeze the most use I can from a by using it for different purposes at different times (exit flag, loop index, temp storage for value to reorder). Normally a very bad programming practice.

So the algorithm is basically that I loop through the Stack elements. Any time I find an element that is greater than the next, then I remove it, and then place it at the end of the Stack. At that moment, I stop the loop, and reset a to -1 to make sure I start the loop again. I keep doing this until I am able to loop through all the stack items without needing to reorder anything.

EDIT 2: Here is another alternative that is a bit more complicated to read, but still respects the rules, and performs better following the bubble sort pattern. The principles used are pretty much the same as my first attempt (abusing the Stack as a List + using variable a for multiple uses).

Stack<Integer> s=new Stack<Integer>();
s.push(5);s.push(3);s.push(4);s.push(1);s.push(1);

int a = -1;
while (a < 0) { // keep looping if the previous loop performed at least one swap.
    a = 0;

    // if 'a' is >= 0, then it simply holds the index.
    // if 'a' < 0, then the index can be obtained by applying the bitwise complement operator.
    while ((a < 0 ? ~a : a) < (s.size() - 1)) { // loop all items except the last one.
        if (s.get(a < 0 ? ~a : a) > s.get((a < 0 ? ~a : a) + 1)) { // if this item is greater than the next, a swap is needed.
            s.insertElementAt(s.remove(a < 0 ? ~a : a), (a < 0 ? ~a : a) + 1); // swap this value with the next.

            // If this was not done already, flag the fact that a swap was performed by
            // applying the bitwise complement operator to 'a'.
            // This serves as a flag to let the outer loop know
            // that we'll need to perform the stack loop again.
            if (a >= 0) {
                a = ~a;
            }
        }

        // increment index. Or if the bitwise complement operator was applied,
        // then go the opposite way since the value is now negative.
        if (a >= 0) {
            a++;
        } else {
            a--;
        }
    }
}

EDIT 3: Revised my last algorithm to use the bitwise complement operator rather than Math.abs().

Also, I would like to point out that, unlike some other clever attempts, this algorithm doesn't really have any limitations. It won't potentially suffer from a StackOverflowException because of too many recursive calls, because no recursion is used. Memory used is stable. And you can have any int value in the Stack, even negative ones, and it will work fine.

Sign up to request clarification or add additional context in comments.

2 Comments

What if you are to treat this as a pure LIFO structure? Treating it as a vector flies in the face of that.
@Makoto: But that's not a requirement of the question. all I'm told is to limit myself to using the Java Stack object and the extra int variable, and that's what I'm doing. If anything, as an interview question, it shows that I understand that the java's Stack class is different from that of other languages. The question already has some pretty unusual requirements to begin with, I don't see anything wrong with thinking a little outside the box to get around the restrictions.
1

It's possible to do, but you're going to be cheating a little bit - you're going to use a second stack to do it.

I don't mean that you're explicitly declaring another stack; you're going to be recursing through this method.

Bear in mind that this approach has some limitations; it can handle sequential data just fine (that is, it can reverse a stack just fine), but dealing with more jumbled data is a lot trickier as we can only see up to two elements in the future (peek and holder).

This also inverts the approach and doesn't order them in a way you'd prescribe (1 to 5), but figuring out the correct condition from the code should be a trivial matter.

The approach is:

  • Handle null and empty stacks by returning what was given to us
  • Handle a stack of size 1 by returning what was given to us
  • In the process, we pop the stack and store that in the holder variable.
  • If what's in the stack next is less than the holder variable, we act:

    • Pop the stack again, multiply it by 10, and add this to the holder. We do the multiplication here so that we can (roughly) store two ints at once.
    • Push the remainder value (holder % 10) into the stack.
    • Recurse, repeating the instructions.
    • Once recursion has exhausted, we push the value we multiplied by 10 back onto the array by dividing the holder by 10.
  • Otherwise, we put back what we had found and return the stack.


public Stack<Integer> sortStack(Stack<Integer> stack) {
    // no-op on empty stacks
    if(null == stack || stack.empty()) {
        return stack;
    }

    // pop stack and place in holder
    while(true) {
        int holder = stack.pop();
        // no-op on stacks of size 1
        try {
            stack.peek();
        } catch(EmptyStackException e) {
            // Stack only had one element; put it back and return the stack
            stack.push(holder);
            return stack;
        }
        if(stack.peek() < holder) {
            holder += stack.pop() * 10;
            stack.push(holder % 10);
            stack = sortStack(stack);
            stack.push(holder / 10);
        } else {
            //put it back
            stack.push(holder);
            break;
        }
    }
    return stack;
}

1 Comment

Your algo is pretty cool! But it won't work with any number in the stack. If I add a 10 to the stack, for instance, the stack gets corrupted. The numbers get changed.
0

Since Stack implements List and Integer implements Comparable just:

Collections.sort(s);

1 Comment

In the comments, OP specified not to use that solution. In your defense, he should probably edit his question to make it clearer though. By the way, to whoever is downvoting the answers (because it wasn't me), it's good practice to leave a comment explaining why you are downvoting an answer.
0

You can use bubble sort to do it, as the following:

Stack<Integer> s = new Stack();
        s.push(5);
        s.push(3);
        s.push(4);
        s.push(1);
        s.push(1);

        int a = 0;
        while (a != s.size() - 1) {
            if (a != s.size() - 1) {
                if (s.elementAt(a) >= s.elementAt(a + 1)) {
                    a++;
                } else {
                    s.push(s.remove(a));
                    a = 0;
                }
            }
        }
        System.out.println(s.toString());

Comments

0

Here i found the perfect answer from geeksforgeeks which uses recursion. http://www.geeksforgeeks.org/sort-a-stack-using-recursion/ Just posting the same algorithm here.

Algorithm:

We can use below algorithm to sort stack elements:

sortStack(stack S)
if stack is not empty:
    temp = pop(S);  
    sortStack(S); 
    sortedInsert(S, temp);

Below algorithm is to insert element is sorted order:

sortedInsert(Stack S, element)

if stack is empty OR element > top element
    push(S, elem)
else
    temp = pop(S)
    sortedInsert(S, element)
    push(S, temp)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.