Computer Science: Class 12 — Chapter 3: Stack

3.1 & 3.2 Introduction to Data Structures and Stacks

A data structure defines a mechanism to store, organise, and access data along with operations (processing) that can be efficiently performed on the data. Grouping multiple data elements in a particular way allows for faster accessibility and efficient storage.

A linear data structure is one in which elements are organised in a sequential order. Examples include arrays, linked lists, stacks, and queues.

A Stack is a linear data structure that follows the Last-In-First-Out (LIFO) principle. In a stack, addition of new elements and removal of existing elements occur at the same end, commonly referred to as the TOP of the stack. The element inserted last is always the first one to be retrieved.

Core Computer Science Concept Technical Definition / Operational State Structural Parameters & Specifications Computational Function & System Purpose
Data Structure A systematic way of organizing and storing data in a computer so that it can be used efficiently. Can be linear (sequential) or non-linear (hierarchical/graphical). Examples: String, List, Tuple, Set, Stack, Queue. Optimizes memory utilization and reduces computational complexity of data access and manipulation.
Stack A sequential linear data structure operating under the Last-In-First-Out (LIFO) discipline. Single-ended access point called TOP . Supports PUSH and POP operations. Manages temporary state storage, function call execution contexts, and expression evaluation.
3.2.1 Applications of Stack

Stacks are widely used in both real-life scenarios and computer science applications:

  • Real-Life Examples: A pile of clothes in an almirah, a vertical pile of chairs, bangles worn on a wrist, or a pile of boxes on a kitchen shelf.
  • String Reversal: Reversing a string by traversing it from start to end, pushing each character onto a stack, and then popping them off sequentially.
  • Undo/Redo Operations: Text and image editors use a stack to track changes, allowing users to revert to the most recent state.
  • Web Browser History: Browsers maintain a history of visited pages in a stack. Clicking the "BACK" button pops the current page to reveal the previously visited page.
  • Parenthesis Matching: Compilers use stacks to verify that every opening parenthesis has a corresponding closing parenthesis in nested arithmetic expressions.
3.3 Operations on Stack

A stack supports two fundamental operations that modify its state:

3.4 Implementation of Stack in Python

In Python, a stack can be easily implemented using the built-in list data type. The list methods append() and pop() naturally insert and delete elements at the rightmost end (the end of the list), which serves as the TOP of the stack. This eliminates the need for an explicit TOP pointer variable.

Technical Profile: Python List-Based Stack

  • Architecture Layer / Tier: High-level dynamic array implementation within the Python standard runtime.
  • Operational Mechanics & Syntax: Uses list.append(item) for PUSH and list.pop() for POP. Custom helper functions check for empty states and size.
  • System Trade-offs & Failures: Python lists dynamically resize, meaning overflow is rarely encountered unless system memory is completely exhausted. However, calling pop() on an empty list raises an IndexError ( underflow ).

Below is a complete Python program implementing a stack of glasses:

  
  def isEmpty(glassStack):
    if len(glassStack) == 0:
        return True
    else:
        return False

def opPush(glassStack, element):
    glassStack.append(element)

def size(glassStack):
    return len(glassStack)

def top(glassStack):
    if isEmpty(glassStack):
        print('Stack is empty')
        return None
    else:
        x = len(glassStack)
        element = glassStack[x-1]
        return element

def opPop(glassStack):
    if isEmpty(glassStack):
        print('underflow')
        return None
    else:
        return glassStack.pop()

def display(glassStack):
    x = len(glassStack)
    print("Current elements in the stack are: ")
    for i in range(x-1, -1, -1):
        print(glassStack[i])

3.5 Notations for Arithmetic Expressions

Arithmetic expressions can be represented in three distinct notations depending on the placement of operators relative to their operands:

Type of Expression Description Example
Infix Notation Operators are placed in between the operands. Requires parentheses and operator precedence rules (BODMAS). $x \\times y + z$
$3 \\times (4 + 5)$
$(x + y) / (z \\times 5)$
Prefix Notation (Polish Notation) Operators are placed before their corresponding operands. Parentheses are unnecessary. $+ \\times x y z$
$\\times 3 + 4 5$
$/ + x y \\times z 5$
Postfix Notation (Reverse Polish Notation) Operators are placed after their corresponding operands. Parentheses are unnecessary. $x y \\times z +$
$3 4 5 + \\times$
$x y + z 5 \\times /$
3.6 Conversion from Infix to Postfix Notation

Compilers convert human-readable infix expressions to postfix expressions to eliminate ambiguity and evaluate expressions in a single linear scan without needing parentheses.

Algorithm 3.1: Infix to Postfix Conversion
  1. Create an empty string named postExp to store the converted postfix expression.
  2. Input the infix expression into a variable, say inExp .
  3. For each character in inExp , repeat Step 4:
  4. Step 4:
    • IF character is a left parenthesis ( , THEN PUSH it onto the Stack.
    • ELSE IF character is a right parenthesis ) , THEN POP elements from the Stack and append them to postExp until the corresponding left parenthesis is popped. Discard both parentheses.
    • ELSE IF character is an operator:
      • IF its precedence is lower than or equal to the operator at the top of the Stack, POP elements from the Stack and append them to postExp until an operator with lower precedence is encountered, then PUSH the current operator onto the Stack.
      • ELSE, PUSH the operator onto the Stack.
    • ELSE, append the character (operand) directly to postExp .
  5. Pop any remaining elements from the Stack and append them to postExp until the Stack is empty.
  6. Output postExp .

Example Trace: Convert the infix expression $(x + y) / (z \\times 8)$ to postfix notation.


Socio-Technical Analysis & Core Systemic Impact: This conversion process ensures that operators with higher precedence are positioned after their operands in the exact order they must be executed. The stack acts as a temporary holding area for operators, deferring their placement until their operands have been processed. The resulting postfix expression is $x y + z 8 \\times /$, which can be evaluated linearly without backtracking.

3.7 Evaluation of Postfix Expression

Postfix expressions are evaluated using a stack by processing the expression from left to right. Operands are pushed onto the stack, and operators trigger the retrieval and processing of these operands.

Algorithm 3.2: Evaluation of Postfix Expression
  1. Input the postfix expression in a variable, say postExp .
  2. For each character in postExp , repeat Step 3:
  3. Step 3:
    • IF the character is an operand, PUSH it onto the Stack.
    • ELSE (the character is an operator), POP the top two elements from the Stack, apply the operator to these elements (the first popped element is the right operand, the second is the left operand), and PUSH the computed result back onto the Stack.
  4. IF the Stack has a single element, POP it and output it as the net result. ELSE, output "Invalid Postfix expression".

Example Trace: Evaluate the postfix expression $7\ 8\ 2\ \times\ 4\ /\ +$.


Socio-Technical Analysis & Core Systemic Impact:
1. Push $7$, $8$, and $2$ onto the stack. [Stack: $7, 8, 2$]
2. Encounter operator $\\times$. Pop $2$ and $8$. Compute $8 \\times 2 = 16$. Push $16$. [Stack: $7, 16$]
3. Push $4$ onto the stack. [Stack: $7, 16, 4$]
4. Encounter operator $/$. Pop $4$ and $16$. Compute $16 / 4 = 4$. Push $4$. [Stack: $7, 4$]
5. Encounter operator $+$. Pop $4$ and $7$. Compute $7 + 4 = 11$. Push $11$. [Stack: $11$]
6. End of expression. Pop the final result: $11$.