Sorting numbers on the stack using a single int variable

I have a Stack variable (java collection) that contains five integers and I was also given one int variable. Is it possible to sort the numbers on the given stack. I cannot work it out. Please post here if you have any 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 shouldn't create a new variable other than the one in the above code snippet, nor should we use Collections.sort (s).

+3


source to share


5 answers


I found the perfect answer here from geeksforgeeks that uses recursion. http://www.geeksforgeeks.org/sort-a-stack-using-recursion/ Just post the same algorithm here.

Algorithm:

We can use the below algorithm to sort the stack items:



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

      

Below the algorithm is to sort the ordered item:

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)

      

0


source


Terribly inefficient, but follows 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 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 am using the fact that I know Stack

extends Vector

. Therefore, I do not need to use only the standard methods Pop

and Push

to access / delete items. I can use the usual methods List

.

And then I just squeeze the best possible use a

by using it for different purposes at different times (exit flag, loop index, temporary storage to override the value). Usually very bad programming practice.

So the algorithm is basically that I go through the Stack elements. Every time I find an element that is larger than the next one, I remove it and then push it to the end of the stack. At this point, I will stop the loop and reset a

to -1

to make sure I start the loop again. I keep doing this until I can loop through all the elements of the stack without having to reorder anything.



EDIT 2 : Here's another alternative that is a little harder to read but still follows the rules and works better after the bubble sort pattern. The principles used are pretty much the same as my first attempt (abuse Stack

like List

+ using a 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 instead of Math.abs()

.

Also, I would like to point out that, unlike some other clever attempts, this algorithm has no limitations. It won't suffer from StackOverflowException

too many recursive calls because no recursion is used. The memory used is stable. And you can have any value int

in Stack

, even negative ones, and it will work just fine.

+2


source


It can be done, but you are going to cheat a little - you are going to use a second stack to do it.

I don't mean that you are explicitly declaring another stack; you will recursively traverse this method.

Be aware that this approach has some limitations; it can handle sequential data just fine (i.e. it can change the stack completely), but dealing with more complex data is much more difficult since we can only see up to two elements in the future (peek and holder).

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

An approach:

  • Handle null

    and empty

    stacks, returning what was given to us
  • Process a stack of size 1, returning what was given to us
  • In this process, we pop the stack and store it in a holder variable.
  • If what's on the stack is smaller than the holder variable, we proceed:

    • Repeat the stack, multiply it by 10 and add to the holder. We do this multiplication so that we can (roughly) store two ints at once.
    • Push the remaining value (holder% 10) onto the stack.
    • Recurse by repeating instructions.
    • Once the recursion is exhausted, we push the value times 10 back by the array, dividing the holder by 10.
  • Otherwise, we will return what we 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


source


Since it Stack

implements List

and Integer

implements Comparable

only:

Collections.sort(s);

      

0


source


You can use bubble sort to do this as shown below:

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

Run codeHide result


0


source







All Articles