Download as pdf or txt
Download as pdf or txt
You are on page 1of 13

ITE 2142 –Data Structures & Algorithms Week 04

LESSON 04 – THE STACK

Introduction

One of the most useful data structure is that of the stack. In this lesson we shall examine this
deceptively simple data structure and see why it plays such a prominent role in the areas of
programming and programming languages. We shall define the abstract concept of a stack and show
how that concept can be made into a concrete and valuable tool in problem solving.

Learning outcome

On successful completion of this lesson you would be able to define and implement stack abstract
data type using arrays and identify basic operations related to stack. Thus you should be able to,

• Define and implement stack abstract data type using arrays & linked lists
• Identify basic operations related to stack

4.1 The stack

Think about arrival of letters to the table of a Manager. In this scenario letters are
arrived one after another and they are packed on the table in a way that newly arrived
letter is on the top of the pack. It is obvious that manager reads the letter one after
another. So he will firstly read the letter that arrives last since it is in the top of the
pack. This real scenario directly maps with stack concept.

A stack is an ordered collection of items may be inserted and from which items may be deleted at
one end, called the top of the stack.

Unlike an array, the definition of the stack provides for the insertion and deletion of items, so that a
stack is dynamic, constantly changing object. You may ask a question, how does a stack change?
The definition specifies that a single end of the stack is designated as the stack top. New items may
be put on top of the stack, or items which are at the top of the stack may be removed.

1
The Stack
ITE 2142 –Data Structures & Algorithms Week 04

4.2 Stack Operations

4.2.1 Push and Pop operations

The two changes which can be made to a stack are given special names. When item is added to a
stack, it is pushed onto the stack, and when an item is removed, it is popped from the stack.
In other words, Given an item A, performing the operation push(A) adds the item A to the top of
the stack. Similarly, the operation pop() removes the top element and return it as a method value.
Thus the assignment operation; i = pop(); removes the element at the top of the stack and assigns
its value to i.

For example think about the stack shown in the following figure 4.1. When we call the method
pop(), it will return the top most element (in this case it will return value 123) and final stack state
is shown in the Figure 4.2.

123 top
89
67
45
76
34

Figure 4.1 Stack containing stack terms

89 top
67
45
76
34

Figure 1.2 Stack containing stack terms (after the method pop() is called)

2
The Stack
ITE 2142 –Data Structures & Algorithms Week 04

Note that once top most element is popped top position of the stack is reduced by 1. In other words,
once element is popped top is pointed to the next top most element.

Similarly when we call push(125) method, the new element 125 is inserted to the current stack. This
can be illustrated by the Figure 4.3.

125
top
89

67
45

76

34

Figure 4.3 Stack containing stack terms (after value 25 is pushed)

Note that once an element is pushed to the stack, value of the stack top is increased by one and it
is pointed to the newly inserted item.

In one perspective, because of the push operation which adds elements to a stack, a stack is
sometimes called a pushdown list.
There is no upper limit on the number of items that may be kept in a stack, since the definition does
not specify how many items are allowed in the collection. Pushing another item onto a stack merely
produces a larger collection of items. However, if a stack contains a single item and the stack is
popped, the resulting stack contains no items and it is called the empty stack. Although the push
operation is applicable to any stack, the pop operation cannot be applied to the empty stack because
such a stack has no elements to pop. Therefore before applying the pop operation to stack we must
ensure that stack is not empty. This leads to another operation, which checks whether the stack is
empty or not. If the stack is empty, isempty() method returns the Boolean value TRUE; Otherwise

3
The Stack
ITE 2142 –Data Structures & Algorithms Week 04

it returns value FALSE. In contrast we can introduce another method called isFull(), that is used to
determine whether stack is full or not.

4.2.2 Peek Operation

Peek operation is performed in a stack to determine what the top item on a stack is without removing
it. This operation returns the top element of the stack. Peek operation is not a new operation since
it can be decomposed into a push and pop.

i = peek(); is equivalent to i = pop(); and push(i);

Like the operation pop, peek is not defined for an empty stack. The result of an illegal attempt pop
or access an item from an empty stack is called underflow. Underflow can be avoided by ensuring
that empty() is false before attempting the operation pop() or peek().

4.3 Sequential representation of Stack


Let’s represent a stack using an array. We can define above mentioned functions as follows.
class Stack
{
private int maxSize;
private double[] stackArray;
private int top;

public Stack(int s) // constructor


{
maxSize = s;
stackArray = new double[maxSize]; // create array
top = -1;
}

// push method
public void push(double j)
{
stackArray[++top] = j;
}
4
The Stack
ITE 2142 –Data Structures & Algorithms Week 04

// pop method public double pop()


{
if isEmpty() == FALSE
return NULL;

return stackArray[top--];
}
// peek() method
public double peek()
{
return stackArray[top];
}
//isEmpty() & isFull() methods
public boolean isEmpty()
{
return (top == -1);
}
public boolean isFull()
{
return (top == maxSize-1);
}
} // end class Stack

4.4 link representation of Stack


You have learnt that, stack is a Last In First Out (LIFO) abstract data type and linear data structure.
Stack is an area of memory that holds all local variables and parameters used by any function, and
remembers the order in which functions are called so that function returns occur correctly. Each
time a function is called, its local variables and parameters are “pushed onto” the stack. When the
function returns, these locals and parameters are “popped”. Because of this, the size of a program’s
stack fluctuates constantly as the program is running, but it has some maximum size. Linked list is
a data structure consisting of a group of nodes which together represent a sequence. Here we need
to apply the application of linked list to perform basic operations of stack.

Here is the source code of the Java program to implement stack using linked list. The Java program
is successfully compiled and run on a Windows system. The program output is also shown below.
5
The Stack
ITE 2142 –Data Structures & Algorithms Week 04

1.
2. import java.util.*;
3.
4. /* Class Node */
5. class Node
6. {
7. protected int data;
8. protected Node link;
9.
10. /* Constructor */
11. public Node()
12. {
13. link = null;
14. data = 0;
15. }
16. /* Constructor */
17. public Node(int d,Node n)
18. {
19. data = d;
20. link = n;
21. }
22. /* Function to set link to next Node */
23. public void setLink(Node n)
24. {
25. link = n;
26. }
27. /* Function to set data to current Node */
28. public void setData(int d)
29. {
30. data = d;
31. }
32. /* Function to get link to next node */
33. public Node getLink()
34. {
35. return link;
36. }
37. /* Function to get data from current Node */
38. public int getData()
39. {
40. return data;
41. }
6
The Stack
ITE 2142 –Data Structures & Algorithms Week 04

42. }
43. /* Class linkedStack */
44. class linkedStack
45. {
46. protected Node top ;
47. protected int size ;
48.
49. /* Constructor */
50. public linkedStack()
51. {
52. top = null;
53. size = 0;
54. }
55. /* Function to check if stack is empty */
56. public boolean isEmpty()
57. {
58. return top == null;
59. }
60. /* Function to get the size of the stack */
61. public int getSize()
62. {
63. return size;
64. }
65. /* Function to push an element to the stack */
66. public void push(int data)
67. {
68. Node nptr = new Node (data, null);
69. if (top == null)
70. top = nptr;
71. else
72. {
73. nptr.setLink(top);
74. top = nptr;
75. }
76. size++ ;
77. }
78. /* Function to pop an element from the stack */
79. public int pop()
80. {
81. if (isEmpty() )
82. throw new NoSuchElementException("Underflow Exception") ;
83. Node ptr = top;

7
The Stack
ITE 2142 –Data Structures & Algorithms Week 04

84. top = ptr.getLink();


85. size-- ;
86. return ptr.getData();
87. }
88.
89. /* Class LinkedStackImplement */
90. public class LinkedStackImplement
91. {
92. public static void main(String[] args)
93. {
94. Scanner scan = new Scanner(System.in);
95. /* Creating object of class linkedStack */
96. linkedStack ls = new linkedStack();
97. /* Perform Stack Operations */
98. System.out.println("Linked Stack Test\n");
99. char ch;
100. do
101. {
102. System.out.println("\nLinked Stack Operations");
103. System.out.println("1. push");
104. System.out.println("2. pop");
105. System.out.println("3. check empty");
106. System.out.println("4. size");
107. int choice = scan.nextInt();
108. switch (choice)
109. {
110. case 1 :
111. System.out.println("Enter integer element to push");
112. ls.push( scan.nextInt() );
113. break;
114. case 2 :
115. try
116. {
117. System.out.println("Popped Element = "+ ls.pop());
118. }
119. catch (Exception e)
120. {
121. System.out.println("Error : " + e.getMessage()
);
122. }
123. break;
124.

8
The Stack
ITE 2142 –Data Structures & Algorithms Week 04

125. case 3 :
126. System.out.println("Empty status = "+ ls.isEmpty());
127. break;
128. case 4 :
129. System.out.println("Size = "+ ls.getSize());
130. break;
131. case 5 :
132. System.out.println("Stack = ");
133. ls.display();
134. break;
135. default :
136. System.out.println("Wrong Entry \n ");
137. break;
138. }
139. /* display stack */
140. ls.display();
141. System.out.println("\nDo you want to continue (Type y or n) \n");
142. ch = scan.next().charAt(0);
143.
144. } while (ch == 'Y'|| ch == 'y');
145. }
146. }

4.5 Application of Stacks: Evaluating Postfix Expressions


Ordinarily, people write arithmetic expressions like this (8-3)*(5+6). This is called infix notation.
Computers manage such expressions better using postfix notation instead. In that form, the operators
always follow their operands. So the infix expression “8-3” is written “8 3 –“, “5+6” is written “5 6
+”, and “(8-3)*(5+6)” is written “8 3 – 5 6 + *”.
Note that with postfix notation, there is no need for parenthesis, because there is no ambiguity. Each
operator always operates on the last two values that precede it. So in the postfix expression “8 3 –
5 6 + *”, the “-” operator must operate on the 8 and the 3, the “+” operator must operate on the 5
and the 6, and the “*” operator must operate on the values returned by the “+” and the “-”.
The following program evaluates postfix expressions. Note that the program reads a postfix
expression from the command line and then prints evaluations. The sample run is executed at the
command line as
Java RPN 9 2 A 5 8 4 D S M

9
The Stack
ITE 2142 –Data Structures & Algorithms Week 04

These nine command line arguments are interpreted as 9 2 + 5 8 4 / - *, which is postfix for the
infix expression (9+2) * (5 – (8/4)). This evaluates 33.
Let’s implement this application in Java. We use symbols A, S, M, D for addition, subtraction,
multiplication and division respectively.
public class RPN {
public RPN(String[] args){
Stack stack = new Stack(args.length);
for (int i=0; i<args.length ; i++){
String input = args[i];
if (isAnOperator(input)){
double y = Double.parseDouble((String)stack.pop());
double x = Double.parseDouble((String)stack.pop());
double z = evaluate(x,y,input);
stack.push("" + z);
}
else stack.push(input);
}
}
private boolean isAnOperator(String s){
return (s.length() == 1 && "AMSD".indexOf(s)>=0);
}
private double evaluate (double x, double y, String op){
double z = 0;
if (op.equals("A")) z = x+y;
if (op.equals("S"))z = x-y;
if (op.equals("M"))z = x * y;
else z = x /y ;
System.out.println( x + "" + op + "" + y+ "=" + z);
return z;
}

public static void main(String[] args) {


// TODO Auto-generated method stub
new RPN(args);
}
10
The Stack
ITE 2142 –Data Structures & Algorithms Week 04

The output of the code snippets is ;

9.0 A 2.0 = 11

8.0 D 4.0 = 2.0

5.0 S 2.0 = 3.0

11.0 M 3.0 = 33.0

The program uses a stack to evaluate the postfix expressions. As it parses the input, it distinguishes
the operators (“A”, “S”, “D”, and “M”) from operands (the numeric values). It pushes the operands
on the stack. When it encounters an operator it assumes that the two operands that belong to that
operator are the last two numbers that were pushed on the stack. So it pops them evaluates the
corresponding expression, and then pushes that numeric result back onto the stack. It uses a separate
evaluate() method to evaluate the expression and to print the evaluation.

Activity 4.1
Write a Java program to reverse a given string. For example, when you input a word
“ELEPHANT” you program should be able to produce an output “TNAHPELE”.
Check your answer (See the last page)

Summary
In this lesson you learned about stacks as an ordered collection of items into which new items
may be inserted and from which items may be deleted at one end. You also knew about operations
that can be performed over stacks and its real world application. Next lesson we will learn about
Queue ADT.

11
The Stack
ITE 2142 –Data Structures & Algorithms Week 04

Activity 4.1 - Answer


//////////////////////////////////////////////////////////////// class
Reverser
{ private String input; // input string
private String output; // output string //-------
-------------------------------------------------------
public Reverser(String in) // constructor
{ input = in; }
//--------------------------------------------------------------
public String doRev() // reverse the string
{
int stackSize = input.length(); // get max stack size
StackX theStack = new StackX(stackSize); // make stack

for(int j=0; j<input.length(); j++)


{
char ch = input.charAt(j); // get a char from input
theStack.push(ch); // push it
}
output = "";
while( !theStack.isEmpty() )
{
char ch = theStack.pop(); // pop a char,
output = output + ch; // append to output
}
return output;
} // end doRev()
//--------------------------------------------------------------
} // end class Reverser
////////////////////////////////////////////////////////////////

12
The Stack
ITE 2142 –Data Structures & Algorithms Week 04

class ReverseApp
{
public static void main(String[] args)
{
String input, output;
while(true)
{
System.out.print("Enter a string to be reversed: ");
input = getString(); // read a string from key board
if( input.equals("") ) // quit if [Enter] break;
// make a Reverser
Reverser theReverser = new Reverser(input);
output = theReverser.doRev(); // use it
System.out.println("Reversed: " + output);
} // end while
} // end main()
//--------------------------------------------------------------
public static String getString() throws IOException
{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String s = br.readLine();
return s;
}
//--------------------------------------------------------------
} // end class ReverseApp

13
The Stack

You might also like