Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
6 views

Module 2 Stack

Uploaded by

abhishektm.22ece
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

Module 2 Stack

Uploaded by

abhishektm.22ece
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

Stacks

A stack is a list of homogenous elements in which the addition and deletion of


elements occurs only at one end, called the top of the stack.
• For example, in a cafeteria, the second tray in a stack of trays can be removed
only if the first tray has been removed.
• For another example, to get to your favorite computer science book, which is
underneath your math and history books, you must first remove the math
and history books. After removing these books, the computer science book
becomes the top book—that is, the top element of the stack. Figure 7-1
shows some examples of stacks.

Stack of boxes Stack of books


Stack of trays
Stack of
coins Applied Math
5 World History
C++ Programming
English
Chemistry

FIGURE 7-1 Various examples of stacks

Stack: A data structure in which the elements are added and removed from one
end only; a Last In First Out (LIFO) data structure.
Operations on Stack:
• Push- new element added to the top of the stack
• Pop - removes the top elementfrom the stack.
• Top – pointer which always points to the top of the stack.

To implement a stack, we need at least these six operations, which are described
below;
• initializeStack—Initializes the stack to an empty state.
• isEmptyStack—Determines whether the stack is empty. If the
stack is empty, it returns the value true; otherwise, it returns the
value false.

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36


• isFullStack—Determines whether the stack is full. If the stack is full, it
returns the value true; otherwise, it returns the value false.
• push—Adds a new element to the top of the stack. The input to this
operation consists of the stack and the new element. Prior to this
opera- tion, the stack must exist and must not be full.
• top—Returns the top element of the stack. Prior to this operation,
thestack must exist and must not be empty.
• pop—Removes the top element of the stack. Prior to this operation, the
stack must exist and must not be empty.

The following abstract class stackADT defines these operations as an ADT:

template <class Type>


class stackADT
{
public:
virtual void initializeStack() = 0;
virtual bool isEmptyStack() = 0;
virtual bool isFullStack() = 0;
virtual void push(Type& newItem) = 0;
virtual Type top() = 0;
virtual int pop() = 0;
virtual print()=0;
};
Figure 7-4 shows the UML class diagram of the classstackADT.

stackADT<Type>

+initializeStack(): void
+isEmptyStack(): boolean
+isFullStack(): boolean
+push(Type): void
+top(): Type
+pop(): void

FIGURE 7-4 UML class diagram of the class stackADT

Implementation of Stacks as Arrays


In the stack implementation using array;
• The first element of the stack can be put in the first array slot, the second
element of the stack in the second array slot, and so on.

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36


• The top of the stack is the index of the last element added to the stack.

• In this implementation of a stack, stack elements are stored in an array,


and an array is a random access data structure; that is, you can directly
access any element of thearray.
• By definition, a stack is a data structure in which the elements are
accessed (popped or pushed) at only one end—that is, a Last In First Out
data structure.
• Thus, a stack element is accessed only through the top, not through the
bottom or middle. T
• To keep track of the top position of the array, we can simply declare
another variable, called Top.

The following class, stackType, implements the functions of the abstract class
stackADT.

template <class Type>


class stackType: public stackADT<Type>
{
int maxStackSize; //variable to store the maximum stack size
int stackTop; //variable to point to the top of the stack
Type stack[10];//pointer to the array that holds stack elements

public:
stackType(int Size = 100);
~stackType();
void initializeStack();
bool isEmptyStack();
bool isFullStack();
void push(Type& newItem);
Type top();
Type pop();
void print();
};

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36


Figure 7-5 shows the UML class diagram of the class stackType.

stackType<Type>
-maxStackSize: int
-stackTop: int
-*stack: Type
+initializeStack(): void
+isEmptyStack(): bool
+isFullStack(): bool
+push(Type&): void
+top(): Type
+pop(): void
+stackType(int = 100)
+~stackType()

FIGURE 7-5 UML class diagram of the classstackType

If stackTopis -1, the stack is empty. If stackTopis nonzero, the stack is nonemptyand the
top element of the stack is given by stackTop – 1 because the first stack element is at
position 0.

Figure 7-6 shows this data structure, wherein stack is an object of type stackType.Note
that stackTop can range from 0 to maxStackSize. If stackTop is nonzero, then stackTop - 1
is the index of the top element of the stack. Suppose that maxStackSize= 100.

[99]
.
.
.
.
.
stack [3] D
[2] C stack
maxStackSize 100
[1] B elements
stackTop 4
[0] A
list

FIGURE 7-6 Example of a stack

Initialize Stack
Let us consider the initializeStack operation. Because the value of stackTop indicates
whether the stack is empty, we can simply set stackTop to -1 to initialize the stack. (See

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36


Figure 7-7.)

[99]
.
.
. unused
stack [3] D stack
[2] C
maxStackSize 100
[1] B
stackTop -1
[0] A
list

FIGURE 7-7 Empty stack

The definition of the function initializeStack is as follows:


template <class Type>
void stackType<Type>::initializeStack()
{
stackTop = -1;
}

Empty Stack
We have seen that the value of stackTop indicates whether the stack is empty. If
stackTop is -1, the stack is empty; otherwise, the stack is not empty. The definition
ofthe function isEmptyStackis as follows:
template <class Type>
bool stackType<Type>::isEmptyStack()
{
return(stackTop == -1);
}

Full Stack
Next, we consider the operation isFullStack. It follows that the stack is full if stackTop
is equal to maxStackSize. The definition of the function isFullStackis as follows:
template <class Type>
bool stackType<Type>::isFullStack()
{
return(stackTop == maxStackSize-1);
}

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36


Push
Therefore, the push operation is as follows:
1. Increment stackTop.
2. Store the newItem in the array component indicated by stackTop.
Figure 7-8(a) shows the stack before pushing 'y' into the stack. Figure 7-8(b) shows
the stack after pushing 'y'into the stack.

[99] [99]
.
. .
. .
. y [4]
stack N [3] stack n [3]
stack
N [2] stack n [2] elements
maxStackSize 100 elements maxStackSize 100
U [1] u [1]
stackTop 4 stackTop 4
S [0] S [0]
list list

(a) Before pushing y (b) After pushing y

template <class Type>


void stackType<Type>::push(Type& newItem)
{
if (stackTop != maxStackSize-1)
{
stackTop++; //increment stackTop
stack[stackTop] = newItem; //add newItem at the top
}
else
cout << "Cannot add to a full stack." << endl;
}
If we try to add a new item to a full stack, the resulting condition is called an
overflow.

Return the Top Element


The operation top returns the top element of the stack. Its definition is as follows:
template <class Type>
Type stackType<Type>::top()
{

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36


if(stackTop != -1);

return stack[stackTop]; //return the element of the stack


//indicated by stackTop
}//end top

Pop
To remove, or pop, an element from the stack, we simply decrement stackTop by 1.
Figure 7-9(a) shows the stack before popping 'D' from the stack. Figure 7-9(b) shows
thestack after popping 'D'from the stack.

[99] [99]
. .
. .
. .
stack D [3] stack D [3]
L [2] stack L [2]
maxStackSize 100 maxStackSize 100 stack
O [1] elements O [1] elements
stackTop 4 stackTop 3
B [0] B [0]
list list

(a) Stack before popping D (b) Stack after popping D

FIGURE 7-9 Stack before and after the pop operation

The definition of the function pop is as follows:


template <class Type>
Type stackType<Type>::pop()
{
if (StackTop == -1)
{
cout << "Cannot remove from an empty stack." << endl;
exit(1);
}
return stack[stackTop--]; //decrement stackTop
}

Constructor and Destructor


The constructor with parameters sets the stack size to the size specified by the user,
sets stackTop to 0, and creates an appropriate array in which to store the stack
elements. If the user does not specify the size of the array in which to store the stack
elements, the constructor uses the default value, which is 100, to create an array of
size 100. The destructor simply deallocates the memory occupied by the array (that is,
the stack) and sets stackTop to 0. The definitions of the constructor and destructor are
as follows:
Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36
template <class Type>
stackType<Type>::stackType(int Size)
{
if (Size <= 0)
{
cout << " array size of the stack must be positive." << endl;
return;
}
else
maxStackSize = Size;

stackTop = -1; //set stackTop to -1

}//end constructor

template <class Type>


stackType<Type>::~stackType() //destructor
{
//deallocate the memory occupied
//by the array
}//end destructor

PRINT Stack elements

void stackType<Type>::print()
{
if(stackTop!=-1)
{
for(int i=stackTop;i>=0;i--)
cout<<stack[i]<<endl;
}
}

TABLE 7-1 Time complexity of the operations of the class stackType on a stack with
n elements

Function Time complexity

isEmptyStack O (1)

isFullStack O (1)

initializeStack O (1)

Constructor O (1)

Top O (1)

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36


Push O (1)

Pop O (1)

copyStack O (n)

Destructor O (1)

copy constructor O (n)

Overloading the assignment operator O (n)

Stack Header File(program to implement the stack using array)

#include <iostream>
using namespace std;
template <class Type>
class stackADT
{
public:
virtual void initializeStack() = 0;
virtual bool isEmptyStack() = 0;
virtual bool isFullStack() = 0;
virtual void push(Type& newItem) = 0;
virtual Type top() = 0;
virtual void pop() = 0;
virtual void print()=0;
};

class stackType: public stackADT<Type>


{
int maxStackSize; //variable to store the maximum stack size
int stackTop;//variable to point to the top of stack
Type stack[10]; //pointer to the array stack elements
public:
stackType(int Size = 100);
~stackType();
void initializeStack();
bool isEmptyStack();
bool isFullStack();
void push(Type& newItem);
Type top();
void pop();
void print();
};
stackType<Type>::stackType(int Size)
{
if (Size <= 0)

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36


{
cout << " array size of the stack must be positive." << endl;
return;
}
else
maxStackSize = Size;

stackTop = -1;//set stackTop to -1


}

template <class Type>


stackType<Type>::~stackType() //destructor
{
delete []stack; //deallocate the memory occupied
}
void stackType<Type>::initializeStack()
{
stackTop = -1;
}
bool stackType<Type>::isEmptyStack()
{
return(stackTop == -1);
}
bool stackType<Type>::isFullStack()
{
return(stackTop == maxStackSize-1);
}
void stackType<Type>::push(Type& newItem)
{
if (stackTop != maxStackSize-1)
{
stackTop++; //increment stackTop
stack[stackTop] = newItem; //add newItem at the top
}
else
cout << "Cannot add to a full stack." << endl;
}
Type stackType<Type>::top()
{
if(stackTop != -1);

return stack[stackTop]; //return the element of the stack


}
void stackType<Type>::pop()
{
if (StackTop == -1)
{
cout << "Cannot remove from an empty stack." << endl;
exit(1);
}
stackTop--; //decrement stackTop
}
void stackType<Type>::print()
{
if(stackTop!=-1)

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36


for(int i=Top;i>=0;i--)
cout<<stack[i]<<endl;
}

int main()
{
stackType<type> stack1(50);
stack1.initializeStack();
stack1.push(23);
stack1.push(45);
stack1.push(38);
stack1.pop();
stack1.print();
while (!Stack1.isEmptyStack()) //print Stack
{
cout << stack1.top()endl;
stack1.pop();
}

return 0;
}

Linked Implementation of Stacks


StackTop gives the address (memory location) of the top element of the stack.
The following class implements the functions of the abstract classstackADT:
//Definition of the node
template <class Type>
struct nodeType
{
Type info;
nodeType<Type> *link;
};
class linkedStackType: public stackADT<Type>
{
nodeType<Type> *stackTop; //pointer to the stack

public:
linkedStackType();
~linkedStackType();
bool isEmptyStack();
void initializeStack();
void push(Type& newItem);
Type top();
void pop();
};

Suppose that stack is an object of type linkedStackType. Figure 7-10(a) shows an


empty stack and Figure 7-10(b) shows a nonempty stack

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36


.

stack stack

stackTop stackTop C

(a) Empty stack B

(b) Nonempty stack

FIGURE 7-10 Empty and nonempty linked stacks

In Figure 7-10(b), the top element of the stack is C; that is, the last element pushed
ontothe stack is C.

Default Constructor
The first operation that we consider is the default constructor. The default constructor
initializes the stack to an empty state when a stack object is declared. Thus, this
function sets stackTopto NULL. The definition of this function is as follows:
template <class Type>
linkedStackType<Type>::linkedStackType()
{
stackTop = NULL;
}

Empty Stack
The stack is empty if stackTop is NULL. Also, because the memory for a stack
element is allocated and deallocated dynamically, the stack is never full. (The
stack is full only if we run out of memory.) The definitions of the functions to
implement these operations are as follows:
template <class Type>
bool linkedStackType<Type>::isEmptyStack()
{
return(stackTop == NULL);
}

Initialize Stack
The operation initializeStack reinitializes the stack to an empty state. Because the stack
might contain some elements and we are using a linked implementation of a stack, we

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36


must deallocate the memory occupied by the stack elements and set stackTop to NULL.
The definition of this function is as follows:
template <class Type>
void linkedStackType<Type>:: initializeStack()
{
nodeType<Type> *temp; //pointer to delete the node

while (stackTop != NULL) //while there are elements in


//the stack
{
temp = stackTop; //set temp to point to the
//current node
stackTop = stackTop->link; //advance stackTop to the
//next node
delete temp; //deallocate memory occupied by temp
}
} //end initializeStack

Push
Consider the stack shown in Figure 7-11.

stack
stackTop C

FIGURE 7-11 Stack before the push operation

Figure 7-12 shows the steps of the push operation. (Assume that the new element to
bepushed is 'D'.)

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36


newNode newNode newNode
D D
stack stack stack
stackTop stackTop stackTop D
C C

C
B B

B
A A

A
(a) Create newNode (b) Put newNode on
and store D the top of stack
(c) Make stackTop point
to the top element

As shown in Figure 7-12, to push 'D' into the stack, first we create a new node and
store 'D' into it. Next, we put the new node on top of the stack. Finally, we make
stackTop point to the top element of the stack. The definition of the function push is
as follows:
template <class Type>
void linkedStackType<Type>::push(Type& newElement)
{
nodeType<Type> *newNode; //pointer to create the new node

newNode = new nodeType<Type>; //create the node

newNode->info = newElement; //store newElement in the node


newNode->link = stackTop; //insert newNode before stackTop
stackTop = newNode; //set stackTop to point to top node
}
We do not need to check whether the stack is full before we push an element onto
thestack because in this implementation, logically, the stack is never full.

Return the Top Element


The operation to return the top element of the stack is quite straightforward. Its
definitionis as follows:
template <class Type>
Type linkedStackType<Type>::top()
{
assert(stackTop != NULL); //if stack is empty,
//terminate the program
return stackTop->info; //return the top element
}//end top

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36


Pop
Now we consider the pop operation, which removes the top element of the stack.
Consider the stack shown in Figure 7-13.

stack
stackTop C

FIGURE 7-13 Stack before the pop operation

Figure 7-14 shows the pop operation.

temp
stack
temp
C C
stackTop
stack

B stackTop B stackTop B

A A
A

(a) Make temp point to the (b) Make stackTop point to (c) Delete temp
top element the next element

FIGURE 7-14 Pop operation


As shown in Figure 7-14, first we make a pointer temppoint to the top of the stack. Next
we make stackTop point to the next element of the stack, which will become the top
element of the stack. Finally, we delete temp. The definition of the function pop is as
follows:
template <class Type>
void linkedStackType<Type>::pop()
{
nodeType<Type> *temp; //pointer to deallocate memory

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36


if (stackTop != NULL)
{
temp = stackTop; //set temp to point to the top node

stackTop = stackTop->link; //advance stackTop to the


//next node
delete temp; //delete the top node
}
else
cout << "Cannot remove from an empty stack." << endl;
}//end pop

Print operation
void linkedStackType<Type>::print()
{
nodeType *temp;
if(stackTop!=NULL)
for(temp=first;temp!=NULL;temp=temp->next)
cout<<temp->info<<endl;
}
Table 7-2 summarizes the time complexity of the operations to implement a linked stack.

TABLE 7-2 Time complexity of the operations of the class linkedStackType on a stack with n
elements

Function Time complexity

isEmptyStack O (1)

isFullStack O (1)

initializeStack O (n)

Constructor O (1)

Top O (1)

Push O (1)

Pop O (1)

copyStack O (n)

Destructor O (n)

copy constructor O (n)

Overloading the assignment operator O (n)

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36


Program: Stack implementation using Linked List
#include <iostream>
using namespace std;
template <class Type>
class stackADT
{
public:
virtual void initializeStack() = 0;
virtual bool isEmptyStack() = 0;
virtual bool isFullStack() = 0;
virtual void push(Type& newItem) = 0;
virtual Type top() = 0;
virtual void pop() = 0;
virtual void print()=0;
};

struct nodeType
{
Type info;
nodeType<Type> *link;
};
class linkedStackType: public stackADT<Type>
{
nodeType<Type> *stackTop; //pointer to the stack

public:
linkedStackType();
~linkedStackType();
bool isEmptyStack();
void initializeStack();
void push(Type& newItem);
Type top();
void pop();
};
linkedStackType<Type>::linkedStackType()
{
stackTop = NULL;
}
bool linkedStackType<Type>::isEmptyStack()
{
return(stackTop == NULL);
}

void linkedStackType<Type>:: initializeStack()


{
nodeType<Type> *temp; //pointer to delete the node

while (stackTop != NULL) //while there are elements in


//the stack
{
temp = stackTop; //set temp to point to the
//current node

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36


stackTop = stackTop->link; //advance stackTop to the
//next node
delete temp; //deallocate memory occupied by temp
}
}

void linkedStackType<Type>::push(Type& newElement)


{
nodeType<Type> *newNode; //pointer to create the new node

newNode = new nodeType<Type>; //create the node

newNode->info = newElement; //store newElement in the node


newNode->link = stackTop; //insert newNode before stackTop
stackTop = newNode; //set stackTop to point to the
//top node
}

Type linkedStackType<Type>::top()
{
assert(stackTop != NULL); //if stack is empty,
//terminate the program
return stackTop->info; //return the top element
}
void linkedStackType<Type>::pop()
{
nodeType<Type> *temp; //pointer to deallocate memory

if (stackTop != NULL)
{
temp = stackTop; //set temp to point to the top node

stackTop = stackTop->link; //advance stackTop to the


//next node
delete temp; //delete the top node
}
else
cout << "Cannot remove from an empty stack." << endl;
}

void linkedStackType<Type>::print()
{
nodeType *temp;
if(stackTop!=NULL)
for(temp=first;temp!=NULL;temp=temp->next)
cout<<temp->info<<endl;
}

int main()
{
linkedStackType<int> stack;

//Add elements into stack


stack.push(34);
stack.push(43);
stack.push(27);

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36


stack.push(72);
Stack.pop();
Stack.print();

while (!newStack.isEmptyStack())
{
cout << newStack.top() << endl;
newStack.pop();
}

return 0;
}

Prof. Shyam Sundar V, Dept. of ECE, CITECH, Bangalore-36

You might also like