Need a Stack Class?
by
, 16-Sep-2009 at 07:45 AM (5471 Views)
Amidst all the Arrays & Structs in-depth multi-part series by Sonny Falk, why not take a look at an example of using an array? The code shown here uses a single-dimensional array as the base for a stack class.
A stack is, by definition, a "last in, first out" (LIFO) abstract structure where elements can be added or taken off from only one end, called the "top". A stack can have any abstract data type as an element, but is characterized by two fundamental operations: push and pop.
This class, called cStack, contains all the basic stack operations (peek, push and pop) among others that will make it easy for your applications to handle any stack. cStack uses a variant array property to store the stack you create, allowing a stack to be of any data type you need.
This is what the cStack class looks like:
To use cStack you will need to create a variant array variable when manipulating the whole stack. When manipulating one of the elements in the stack, you will need to create a variable of the data type you are storing in the stack. Something like this:Code:Class cStack is a cObject Procedure Construct_Object Forward Send Construct_Object Property Variant[] pvStack End_Procedure // Construct_Object // Function NumberOfNodesInStack // Returns number of nodes in the stack // -------------------------------------------------------------- Function StackSize Returns Integer Variant[] Stack Get pvStack to Stack Function_Return (SizeOfArray(Stack)) End_Function // Function IsStackEmpty // Returns True if stack is empty // -------------------------------------------------------------- Function IsStackEmpty Returns Boolean Integer iNumStackElements Get StackSize to iNumStackElements Function_Return (iNumStackElements = 0) End_Function // Function Peek // Returns top element of the stack // -------------------------------------------------------------- Function Peek Returns Variant Variant TopOfStack Variant[] Stack Integer iNumOfElements Get pvStack to Stack Move (SizeOfArray(Stack)) to iNumOfElements If (iNumOfElements > 0) Begin Move Stack[iNumOfElements - 1] to TopOfStack End Function_Return TopOfStack End_Function // Function Pop // Remove top node from stack // Returns the top node of the stack that was removed // -------------------------------------------------------------- Function Pop Returns Variant Variant TopOfStack Variant[] Stack Integer iNumOfElements Get pvStack to Stack Move (SizeOfArray(Stack)) to iNumOfElements If (iNumOfElements > 0) Begin Move Stack[iNumOfElements - 1] to TopOfStack Move (ResizeArray(Stack, iNumOfElements - 1)) to Stack Set pvStack to Stack End Function_Return TopOfStack End_Function // Function Push // Adds node to the top of the stack // Returns the index where the new node was placed in the stack // -------------------------------------------------------------- Function Push Variant ElementToAdd Returns Integer Variant[] Stack Integer iNumOfElements Get pvStack to Stack Move (SizeOfArray(Stack)) to iNumOfElements Move ElementToAdd to Stack[iNumOfElements] Set pvStack to Stack Function_Return iNumOfElements End_Function // Procedure ClearStack // Clear the stack // -------------------------------------------------------------- Procedure ClearStack Variant[] Stack Set pvStack to Stack End_Procedure End_Class
When using the cStack class, you may find it better to create a subclass and add code to deal with the specific needs of the elements you are storing in the stack. In a subclass you may simply add functions that will describe better the operations you will be performing, in other words, the name of the functions used in your programs will be more meaningful to what you are doing.Code:// Function CurrentSWSStack // Returns the current SWS stack // -------------------------------------------------------------- Function CurrentSWSStack Returns Variant[] Variant[] StackOfSWSs Get pvStack to StackOfSWSs Function_Return StackOfSWSs End_Function // Function PopSWSFromStack // Remove top node from stack // Returns the top node of the SWS stack that was removed // tSWSDetails: structure that stores contents read from SWS file // -------------------------------------------------------------- Function PopSWSFromStack Returns tSWSDetails tSWSDetails TopOfStack Boolean bEmpty Get IsSWSStackEmpty to bEmpty If (not(bEmpty)) Begin Get Pop to TopOfStack End Function_Return TopOfStack End_Function
For example, for a stack of workspace files (SWS), you may have a function called TopSWS that will really perform a peek and return the top element of the stack, like this:
For anything managed in a LIFO style you can do the same. You may want to create a subclass to organize the latest news. In your subclass you can create a function called ReadNews which will perform pops on your stack, LatestNews. You may also create a function to ReadLatest that will really perform a peek on LatestNews.Code:// Function IsSWSStackEmpty // Returns True if stack is empty // -------------------------------------------------------------- Function IsSWSStackEmpty Returns Boolean Boolean bEmpty Get IsStackEmpty to bEmpty Function_Return bEmpty End_Function // Function TopSWS // Returns top node of the SWS stack // tSWSDetails: structure that stores contents read from SWS file // -------------------------------------------------------------- Function TopSWS Returns tSWSDetails tSWSDetails TopOfStack Boolean bEmpty Get IsSWSStackEmpty to bEmpty If (not(bEmpty)) Begin Get Peek to TopOfStack End Function_Return TopOfStack End_Function
Note: If you need to do a very high number of push or pop operations (e.g. a loop to perform push/pop through many, many, many elements of your stack), you should consider updating the array property from the class straight into your code instead of using the class push/pop access methods. Access methods that translate into a Get-Modify-Set transaction will negatively affect performance when highly used, as Sonny will explain in his future posts. Stay tuned.
As you can see, a cStack object should be able to handle any kind of elements, including object handles. This class should give you the flexibility and the functionality you were looking for. Try it out!