Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stack<> implementation in C#

Tags:

stack

c#

I've recently been implementing a recursive directory search implementation and I'm using a Stack to track the path elements. When I used string.Join() to join the path elements, I found that they were reversed. When I debugged the method, I looked into the stack and found that the elements themselves were reversed in the Stack's internal array, ie the most recently Push()ed element was at the beginning of the internal array, and the least recently Push()ed element was at the end of the internal array. This seems ass-backward and very counter-intuitive. Can somebody please tell me why Microsoft would implement a stack in such a manner ?

like image 505
Alex Marshall Avatar asked Jul 09 '10 17:07

Alex Marshall


People also ask

How is stack implemented in C?

What is Stack Structure in C? A stack is a linear data structure which follows LIFO (last in first out) or FILO (first in last out) approach to perform a series of basic operation, ie. Push, Pop, atTop, Traverse, Quit, etc. A stack can be implemented using an array and linked list.

What is stack and its implementation?

A stack is an Abstract Data Type (ADT), commonly used in most programming languages. It is named stack as it behaves like a real-world stack, for example – a deck of cards or a pile of plates, etc. A real-world stack allows operations at one end only.

What are the alternative implementation of stacks and queue in C?

Both stacks and queues in C are data structures that can be implemented using either arrays or linked lists.

What is mean by stack in C?

It is a linear data structure that follows a particular order in which the operations are performed. LIFO( Last In First Out ): This strategy states that the element that is inserted last will come out first.


2 Answers

I think you're mistaken.

It isn't that Stack<T>.Push internally inserts an item at the start of its internal array (it doesn't). Rather, it enumerates from the top to the bottom, as this is the manner in which one would intuitively enumerate through a stack (think of a stack of pancakes: you start at the top and work your way down).

If you look at the contents of a collection from within Visual Studio's debugger, I think it will display them to you in the order they're enumerated -- not the order they're stored internally*.

Take a look at the Stack<T>.Push method in Reflector and you'll see that the code is basically exactly what you'd expect:

// (code to check array size)
this._array[this._size++] = item;
// (code to update internal version number)

So the stack internally adds new elements onto the end of its internal array. It's the Stack<T>.Enumerator class that's got you confused, not the Stack<T> class itself.

*I don't know whether this is true in general, but it's true for Stack<T>; see Hans Passant's excellent answer for the reason why.

like image 111
Dan Tao Avatar answered Nov 15 '22 19:11

Dan Tao


You had me going there for a bit, that indeed looks completely bass-ackwards. There is however something else going on. The Stack<> class has a debugger visualizer, named System_StackDebugView<>. It is an internal class, you'd have to look with Reflector to see it.

That visualizer has an Items property, that's what you look at when you expand the node in the debugger. That Items property uses Stack<>.ToArray(). Which looks like this:

public T[] ToArray()
{
    T[] localArray = new T[this._size];
    for (int i = 0; i < this._size; i++)
    {
        localArray[i] = this._array[(this._size - i) - 1];
    }
    return localArray;
}

Yup, backwards.

like image 26
Hans Passant Avatar answered Nov 15 '22 21:11

Hans Passant