The stack is a common data structure for representing things that need to maintained in a particular order. For instance, when a function calls another function, which in turn calls a third function, it's important that the third function return back to the second function rather than the first.

 

 

One way to think about this implementation is to think of functions as being stacked on top of each other; the last one added to the stack is the first one taken off. In this way, the data structure itself enforces the proper order of calls.

Conceptually, a stack is simple: a data structure that allows adding and removing elements in a particular order. Every time an element is added, it goes on the top of the stack; the only element that can be removed is the element that was at the top of the stack. Consequently, a stack is said to have "first in last out" behavior (or "last in, first out"). The first item added to a stack will be the last item removed from a stack.

So what's the big deal? Where do stacks come into play? As you've already seen, stacks are a useful way to organize our thoughts about how functions are called. In fact, the "call stack" is the term used for the list of functions either executing or waiting for other functions to return.

In a sense, stacks are part of the fundamental language of computer science. When you want to express an idea of the "first in last out" variety, it just makes sense to talk about it using the common terminology. Moreover, such operations show up an awful lot, from theoretical computer science tools such as a push-down automaton to AI, including implementations of depth-first search.

Stacks have some useful terminology associated with them:

  • PushTo add an element to the stack
  • PopTo remove an element from the stock
  • PeekTo look at elements in the stack without removing them
  • LIFORefers to the last in, first out behavior of the stack
  • FILOEquivalent to LIFO
/*
-------------------------------------------------------------------
| |
| Stack Class |
| =========================================================== |
| This Stack has been implemented with templates to allow it |
| to accomodate virtually any data type, and the size of the |
| Stack is determined dynamically at runtime. |
| |
| There is also a new function: peek(), which, given a whole |
| number 'Depth', returns the Stack element which is 'Depth' |
| levels from the top. |
| |
-------------------------------------------------------------------
*/

#ifndef __StackClassH__
#define __StackClassH__

#include <assert.h> // For error-checking purposes

//-------------------------------------------------
// Main structure of Stack Class:
//-------------------------------------------------

template <class Elem>
class Stack
{
public:
Stack(int MaxSize=500);
Stack(const Stack<Elem> &OtherStack);
~Stack(void);

inline void Push(const Elem &Item); // Adds Item to the top
inline Elem Pop(void); // Returns Item from the top
inline const Elem &Peek(int Depth) const; // Peek a depth downwards

protected:
Elem *Data; // The actual Data array
int CurrElemNum; // The current number of elements
const int MAX_NUM; // Maximum number of elements
};

//-------------------------------------------------
// Implementation of Stack Class:
//-------------------------------------------------

// Stack Constructor function
template <class Elem>
Stack<Elem>::Stack(int MaxSize) :
MAX_NUM( MaxSize ) // Initialize the constant
{
Data = new Elem[MAX_NUM];
CurrElemNum = 0;
}

// Stack Destructor function
template <class Elem>
Stack<Elem>::~Stack(void)
{
delete[] Data;
}

// Push() function
template <class Elem>
inline void Stack<Elem>::Push(const Elem &Item)
{
// Error Check: Make sure we aren't exceeding the maximum storage space
assert(CurrElemNum < MAX_NUM);

Data[CurrElemNum++] = Item;
}

// Pop() function
template <class Elem>
inline Elem Stack<Elem>::Pop(void)
{
// Error Check: Make sure we aren't popping from an empty Stack
assert(CurrElemNum > 0);

return Data[--CurrElemNum];
}

// Peek() function
template <class Elem>
inline const Elem &Stack<Elem>::Peek(int Depth) const
{
// Error Check: Make sure the depth doesn't exceed the number of elements
assert(Depth < CurrElemNum);

return Data[ CurrElemNum - (Depth + 1) ];
}

#endif /*__StackClassH__*/