The stack is a list-like structure
in which elements may be inserted or removed from only one end.
While this restriction makes stacks less flexible than lists,
it also makes stacks both efficient (for those operations they can do)
and easy to implement.
Many applications require only the limited form of
insert and remove operations that stacks provide.
In such cases, it is more efficient to use the simpler stack data
structure rather than the generic list.
For example, the freelist is really a
stack.
Despite their restrictions, stacks have many uses.
Thus, a special vocabulary for stacks has developed.
Accountants used stacks long before the invention of the computer.
They called the stack a “LIFO” list,
which stands for “Last-In, First-Out.”
Note that one implication of the LIFO policy is that stacks
remove elements in reverse order of their arrival.
The accessible element of the stack is called the top element.
Elements are not said to be inserted, they are pushed
onto the stack.
When removed, an element is said to be popped from the
stack.
Here is a simple stack ADT.
publicinterfaceStack{// Stack class ADT// Reinitialize the stack.publicvoidclear();// Push "it" onto the top of the stackpublicbooleanpush(Objectit);// Remove and return the element at the top of the stackpublicObjectpop();// Return a copy of the top elementpublicObjecttopValue();// Return the number of elements in the stackpublicintlength();// Return true if the stack is empty publicbooleanisEmpty();}
publicinterfaceStack<E>{// Stack class ADT// Reinitialize the stack.publicvoidclear();// Push "it" onto the top of the stackpublicbooleanpush(Eit);// Remove and return the element at the top of the stackpublicEpop();// Return a copy of the top elementpublicEtopValue();// Return the number of elements in the stackpublicintlength();// Tell if the stack is empty or notpublicbooleanisEmpty();}
As with lists, there are many variations on stack implementation.
The two approaches presented here are the array-based stack
and the linked stack,
which are analogous to array-based and linked lists, respectively.
classAStackimplementsStack{privateObjectstackArray[];// Array holding stackprivatestaticfinalintDEFAULT_SIZE=10;privateintmaxSize;// Maximum size of stackprivateinttop;// First free position at top// ConstructorsAStack(intsize){maxSize=size;top=0;stackArray=newObject[size];// Create stackArray}AStack(){this(DEFAULT_SIZE);}publicvoidclear(){top=0;}// Reinitialize stack// Push "it" onto stackpublicbooleanpush(Objectit){if(top>=maxSize)returnfalse;stackArray[top++]=it;returntrue;}// Remove and return top elementpublicObjectpop(){if(top==0)returnnull;returnstackArray[--top];}publicObjecttopValue(){// Return top elementif(top==0)returnnull;returnstackArray[top-1];}publicintlength(){returntop;}// Return stack sizepublicbooleanisEmpty(){returntop==0;}// Check if the stack is empty}
classAStack<E>implementsStack<E>{privateEstackArray[];// Array holding stackprivatestaticfinalintDEFAULT_SIZE=10;privateintmaxSize;// Maximum size of stackprivateinttop;// First free position at top// Constructors@SuppressWarnings("unchecked")// Generic array allocationAStack(intsize){maxSize=size;top=0;stackArray=(E[])newObject[size];// Create stackArray}AStack(){this(DEFAULT_SIZE);}publicvoidclear(){top=0;}// Reinitialize stack// Push "it" onto stackpublicbooleanpush(Eit){if(top>=maxSize){returnfalse;}stackArray[top++]=it;returntrue;}// Remove and return top elementpublicEpop(){if(top==0){returnnull;}returnstackArray[--top];}publicEtopValue(){// Return top elementif(top==0){returnnull;}returnstackArray[top-1];}publicintlength(){returntop;}// Return stack sizepublicbooleanisEmpty(){returntop==0;}// Tell if the stack is empty}
The array-based stack implementation is essentially
a simplified version of the array-based list.
The only important design decision to be made is which end of the
array should represent the top of the stack.
One choice is to make the top be at position 0 in the array. In terms of list functions, all push and pop operations would then be on the element at position 0.