views:

2068

answers:

11

How would you invert a stack, without using extra data structures, like a second, or temporary, stack. Thus no stack1-stack2 or stack-queue-stack implementation in the answer. You just have access to push/pop feature of a standard stack.

I think there is way to do it by keeping a global counter and using pointer manipulation.

+2  A: 

Does stack-stack count? You do not need a different data structure that way. In this case pop an element and push it onto the other stack. Do this for all elements and you inverted the stack. On the downside of it is that you get another stack, it is not inplace.

If you, as you added to your question, want to do this using pointers and counters, it is very implementation depended and violates the definition of a stack. Your solution can be broken at any new release or change of implementation of the stack. I would refrain from doing this. (This of course is different if you implement your own stack, but then you could use a different data structure in the first place to represent your problem more accurately.)

Ralph Rickenbach
s1.push(s2.pop);no i didnot mean this answer.
vks
As others have said, the only way to get something from a stack is pop. Therefore this is it. You will have to be more explicit in your question, then.
Ralph Rickenbach
+15  A: 

As a stack only gives you access to the top element, it's not possible to invert (reverse the or order of) without using some additional storage. The most minimal that I can think of (only weakly exception safe) is something like:

template<class T>
void Invert( std::stack<T>& a_stack )
{
    std::stack<T> tmp;

    while( !a_stack.empty() )
    {
        tmp.push( a_stack.top() );
        a_stack.pop();
    }

    std::swap( a_stack, tmp );
}
Charles Bailey
Then it's not possible without access to the internal storage or implementation of the stack. Using the standard interface for a stack, you need external storage to reverse it.
Charles Bailey
yes it is possible, write your own wrapper to it
vks
This is not the right answer. I cant vote it down. :-X
vks
You need to explain how an interface that wraps a stack can reverse the stack without itself using additional storage. I don't believe that it's possible, but if you believe it is then you should post an example.
Charles Bailey
@Vivek Sharma, It is the right answer, you are wrong. You are relying on the internal representation of a stack which is a different question.
KingNestor
@Thangalin, using recursion is substituting the systems stack for an external one, and is no better.
Simucal
Using recursion with a function with a local variable *is* using external storage.
Charles Bailey
@Simucal - Never said it was better; I merely stated that it could be done without an additional data structure.@Charles - The key phrase, in my mind, was "data structure". A local variable (such as an integer) is not, technically, a data structure.
Dave Jarvis
+6  A: 

If your stack is implemented as a linked list (and you have access to the implementation), then run through the linked list reversing the direction then point head at the new tail.

// oh man, I think this is right
cur = head;
while(cur->next)
{
   tmp = cur->next->next;
   cur->next->next = cur;
   cur = tmp;
}
head->next = null;
head = cur;

Otherwise do what everyone else is saying.

Talljoe
if u are assuming a linked list implementation, then why not think of a doubly linked list. :D
vks
Fair point, but people don't usually use a doubly-linked lists for stacks.
Talljoe
+2  A: 

If your stack is a doubly linked list... just move the top pointer to the bottom :-). Or just reverse the list in place. Even if you had an array implementation, the reversal would be easy. This all assumes that you have access to the innards of the stack. If you can only use pop(), you need other storage.

Tom
By the way, I know for the doubly linked list, it's not as simple as "moving the top pointer to the bottom". The stack method implementations would need to be implemented slightly differently to account for reversibility of the stack... but it can be done easily with not a lot of overhead :-).
Tom
+1  A: 

A stack maybe nothing but an array of objects. Take the midpoint and swap i and length-i elements..

Pradeep
but if know, how they are implemented, u only have access to the top pointer. and nothing else.but you are right, this can be done, if u have all the access to the stack implementation.
vks
+2  A: 

Do you have control of the implementation of your stack?

If so, the stack can easily have a reverse method and be implemented by a double-ended queue. Depending on its mode, it deques from either end on a pop call.

gommo
i think u mean doubly linked list.
vks
No, not really. Although a double-ended queue would probably be implemented by a doubly linked list a queue is definitely implying insertion/deletions only from the ends. Whereas a list 'could' allow indexing (Although not a requirement by any means)
gommo
+26  A: 

A recursive algorithm (bounds checking left for the reader) will solve the problem without explicitly declaring additional data structures (as per the constraints of the question) by using an implicit data structure: the process call stack.

void invert( Stack stack ) {
  Object o = stack.pop();

  invert( stack );
  append( stack, o );
}

void append( Stack stack, Object o ) {
  Object obj = stack.pop();

  append( stack, o );
  stack.push( obj );
}

The invert function pops all the values from the call stack (which is not a new stack data structure instance variable). Once all the values have been popped, they get appended in reverse order via the append method.

See Also

http://discuss.joelonsoftware.com/default.asp?interview.11.312666.6
http://wiki.answers.com/Q/How_do_you_reverse_a_stack_in_place_using_recursion

Dave Jarvis
But now the data from your stack is on the process stack during the recursion!! It's no better than using a local stack object in a non-recursive function.
markh44
This algorithm is O(n). If you have full control over the implementation of the stack, an O(1) solution is possible.
Lars Haugseth
You may not use another data structure, but you're using number-of-stack-elements temporary variables. In what way is this better or memory efficient with regard to the question?
DaClown
This is rather 'begging the question', using the call stack as storage avoids using a dedicated _data_ structure, but it is not usually an efficient place for data storage. Also, you don't seem to have any protection against popping from an empty stack?
Charles Bailey
@markh44 - Yes, but since the process stack is always available, making use of it avoids an "extra" local object -- as was the original question.@Lars - Agreed. The original question seemed to imply the code might not be available.@DaClown - Nothing was asked about being the most efficient use of memory. The question, as I read it, was to not use an additional data structure. All other answers used a second structure, or presumed access to the source code.@Charles - I mentioned "without bounds checking" to indicate it remained for the reader. I agree it is not most efficient.
Dave Jarvis
@Thangalin - a call stack is not always available. When booting an embedded device before getting the memory mapping setup, you don't have a stack.
Simeon Pilgrim
-1 as using the call stack is using 'another stack'
Simeon Pilgrim
@Thangalin: If avoiding 1 local stack of 100 elements is substituted by storing 100 local elements (plus the rest of the parameters passed in and out of the recursive function) the net gain is probably negative.
David Rodríguez - dribeas
Congratulations on coming up for a solution for a poorly phrased and essentially impossible question.
jmtd
@Simeon: when booting an embedded device before memory mapping is set up, you don't write code that needs to invert a stack without using extra data structures.
Jonathan Leffler
@Jonathan: nobody ever writes code that isn't allowed to use extra "data structures", but is allowed to lay down arbitrarily many stack frames, with automatic variables on each. This is a programming-while-handcuffed question, and I don't think it really matters how people interpret the completely unrealistic constraints. Personally I'd interpret "no extra data structures" to mean "O(1) additional storage" (which would be a plausible practical constraint). Otherwise, if "Object" is itself a "data structure", then is this solution valid?
Steve Jessop
When does the recursive `invert` function call stop? There's no stop condition, except maybe an exception when you're popping an item from an empty stack.
Cristian Ciupitu
@Cristian: As written, it will not. Please note the phrase: bounds checking left for the reader.
Dave Jarvis
+2  A: 

This can be done in O(1) if you implement your stack as a doubly linked list with two pointers per node whose semantic meaning can be switched by toggling a direction attribute of the stack. You will also need attributes to keep track of both end nodes. The reverse operation then simply needs to toggle the direction attribute and switch the end node attributes.

Lars Haugseth
this u can do it only if u have access to stack implementation, else you need to do recursive approach discussed above to do it without using any additional memory
Learner
A: 

so your question is:

I have a stack of objects, how do I invert the stack using only the push and pop functions and not storing the objects in any other data structure?

answer: you can't.

I think the better question is WHY?

matt
why the downvote? did I say something wrong??
matt
A: 

use two statcks

A: 

Working code:

    /**
 * http://stackoverflow.com/questions/1072903/invert-a-stack-without-using-extra-data-structures
 * 
 * @param s
 */
public static void revertStack(Stack<Integer> s) {
    if (s.isEmpty()) {
        return;
    } else {
        Integer a = s.pop();
        revertStack(s);
        appendStack(s, a);
    }
}

public static void appendStack(Stack<Integer> s, Integer a) {
    if (s.isEmpty()) {
        s.push(a);
        return;
    } else {
        Integer o = s.pop();
        appendStack(s, a);
        s.push(o);
    }
}
Bill Li