UMBC CS 201, Fall 98
UMBC CMSC 201 & 201H Fall '98 CSEE | 201 | 201 F'98 | lectures | news | help

The Stack

Implementation using an array

It is quite possible to use an array to implement a stack, but we would suffer all the same space limitations that we have all along with arrays.

We would have to guess about how big the stack could possibly get, declare an array to be of that size, and then start pushing items. We would just have to hope that our guess was correct, so that the array could hold the entire stack. Otherwise we'd have to abort the program.

Since in our simple example, this array would be holding ints, we would have to initialize all of the elements of the array to hold some integer that wouldn't be a valid integer for this particular application, possibly 0 or -1.

In this implementation, the pointer top would hold the same address as the name of the array.

Pushing is a big problem, since the item is pushed onto the top of the stack, all items already in the stack will have to be moved down one element. The code might look something like this:

/* Go down the stack until an unused element is found */ i = 0; while (array[i] != 0) { i++; } /* Move each of the elements down one element in the array */ while (i > 0) { array[i] = array[i-1]; i--; } /* Now put the value to be pushed into the first element */ array[0] = value; So pushing is extremely time consuming.

Popping is also a problem. Since when we pop something, it has to be removed from the top of the stack (remove array[0]), we will need to move all other values up by one element in the array. As in:

value = array[0]; i = 1; while (array[i] != 0) { array[i - 1] = array[i]; i++; } array[i - 1] = 0; So popping is also quite time consuming.

If we think about implementing the stack using an array, not only are we wasting space, but we are also wasting time. Sometimes it's okay to waste space if it will save us time. Other times it's okay to waste time to save space. It all depends on the needs of the application and there is usually a tradeoff between space and time. It is never okay to waste both space and time. So even though it is possible to implement a stack using an array, it isn't a good idea.

Implementation using a linked list

Since we already know about linked lists, we should consider using a linked list implementation for the stack. The stack can be implemented without wasting any space, and by doing pointer manipulation rather than a series of value moves, we can make our stack work much faster than an array implementation could.

The user interface for the linked list implementation

/************************************************\ * Filename: stack.h * * Author: Sue Bogar * * Date Written: 4/25/98 * * Description: This file contains the function * * prototypes to work with stack.c. * * This set of functions provide the operations * * needed including adding an item to the stack, * * pushing; deleting an item from the stack, * * popping; determining if the stack is empty and * * the printing the items in the stack. * * Since the stack is being implemented as a * * linked list, some functions needed for a list * * have been added to this file. Those functions * * are CreateNode and GetData. * \************************************************/ #ifndef _stack_h #define _stack_h /****************** * This typedef allows us to call the type * of a pointer to a node a nodePtr ******************/ typedef struct tag *nodePtr; /****************** * The queue is being implemented as a linked list * and a linked list requires nodes. Each node is * a structure that has two members, the first to * hold data and the second, of type nodePtr is * a pointer to the next node in the list. ******************/ typedef struct tag { int data; nodePtr next; }node; /****************** * Push takes a pointer to nodePtr as its first * argument, which holds the address of top. * The second argument is a pointer to the node * that's to be inserted. Push will insert the * item at the top of the stack. The address of * top is passed into this function, because the * function may need to change the address held * in top. ******************/ void Push (nodePtr *topPtr, nodePtr temp); /****************** * Pop takes a pointer to a nodePtr as its * only argument. It will hold the address * of top. This function removes an item from * the stack and returns the data value stored * there. This function may alter the value * of top. ******************/ int Pop (nodePtr *topPtr); /****************** * IsEmpty takes a nodePtr as its first * argument, which is top. It determines * if the stack is empty and returns 1 (true) * if the stack is empty and 0 (false) if it * is not empty. ******************/ int IsEmpty (nodePtr head); /****************** * PrintStack takes a nodePtr as an argument * which is initially the top. The stack is * traversed and the value of the data member * of each item is printed. ******************/ void PrintStack (nodePtr curr); /****************** * CreateNode mallocs the space needed to * hold a struct of type node, initializes * the members, and returns a pointer to * the new node. ******************/ nodePtr CreateNode (void); /****************** * GetData gets the value of data * from the user and puts it into the * node pointed to by the nodePtr it * receives as an argument. ******************/ void GetData (nodePtr temp); #endif


CSEE | 201 | 201 F'98 | lectures | news | help

Wednesday, 02-Dec-1998 09:14:16 EST