1. Introduction to Data Structures
- Types of Data Structures — Static, Dynamic, Primitive, Non-Primitive, Linear, Non-Linear
- Stack
- Definition
- Representation
- Operations
- Implementation
- Applications — Conversion of Polish notations, Evaluation of postfix expressions
1.1 Data Structure — Definition
- Examples: Arrays, Linked List, Stack, Queue, Tree, Graph, etc.
- Data Structures are widely used in almost every aspect of Computer Science — Operating System, Compiler Design, Artificial Intelligence, Graphics and many more.
- Data Structures are the main part of many computer science algorithms as they enable programmers to handle data in an efficient way.
- It plays a vital role in enhancing the performance of software or a program — the main function of software is to store and retrieve user data as fast as possible.
1.2 Basic Terminology
Data structures are the building blocks of any program or software. Choosing the appropriate data structure for a program is the most difficult task for a programmer. Following terminology is used as far as data structures are concerned:
| Term | Meaning |
|---|---|
| Data | Data can be defined as an elementary value or the collection of values. Example: student's name and its id are the data about the student. |
| Group Items | Data items which have subordinate data items are called Group item. Example: name of a student can have first name and last name. |
| Record | Record can be defined as the collection of various data items. Example: student entity — name, address, course and marks grouped together form the record for the student. |
| File | A File is a collection of various records of one type of entity. Example: if there are 60 employees in the class, then there will be 60 records in the related file where each record contains data about each employee. |
| Entity | An entity represents the class of certain objects. It contains various attributes. Each attribute represents a particular property of that entity. |
| Attribute | Attribute represents the particular property of an entity. |
| Field | Field is a single elementary unit of information representing the attribute of an entity. |
1.3 Need of Data Structures
As applications are getting complex and amount of data is increasing day by day, the following problems may arise:
- Processor speed: To handle very large amount of data, high speed processing is required. But as data grows day by day to billions of files per entity, processor may fail to deal with that much amount of unorganized data.
- Data Search: Consider an inventory size of 106 items in a store. If application needs to search a particular item, it must traverse 106 items every time — results in slowing down the search process.
- Multiple requests: If thousands of users search data simultaneously on a web server, there are chances that a very large server can fail during that process.
1.4 Advantages of Data Structures
- Efficiency: Efficiency of a program depends upon the choice of data structures. Example: if we organize data in an array, we must search sequentially element by element — not very efficient. Better data structures: ordered array, binary search tree, hash tables.
- Reusability: Data structures are reusable — once implemented, can be used at any other place. Implementation can be compiled into libraries used by different clients.
- Abstraction: Data structure is specified by the ADT which provides a level of abstraction. Client program uses data structure through interface only, without getting into implementation details.
2. Types of Data Structures
Syllabus types: Static, Dynamic, Primitive, Non-Primitive, Linear, Non-Linear — see diagram and distinguish tables below.
2.1 Linear Data Structures
If a data structure organizes data in sequential order, it is called a Linear Data Structure.
Examples: Arrays, List (Linked List), Stack, Queue
Arrays
- An array is a collection of similar type of data items; each data item is called an element of the array.
- Data type of element may be any valid type: char, int, float or double.
- Elements share the same variable name but each carries a different index number (subscript).
- Array can be one dimensional, two dimensional or multidimensional.
- Individual elements:
age[0], age[1], age[2], ... age[98], age[99]
Linked List
- Linked list is a linear data structure used to maintain a list in memory.
- Collection of nodes stored at non-contiguous memory locations.
- Each node contains a pointer to its adjacent node.
Stack
- Stack is a linear list in which insertion and deletions are allowed only at one end called top.
- Stack is an Abstract Data Type (ADT); can be implemented in most programming languages.
- Named stack because it behaves like real-world stack — piles of plates, deck of cards, etc.
Queue
- Queue is a linear list — elements inserted only at one end called rear and deleted only at other end called front.
- Abstract data structure, similar to stack.
- Opened at both ends — follows FIFO (First-In-First-Out) methodology.
2.2 Non-Linear Data Structures
If data is organized in random order (not sequential), it is Non-Linear Data Structure.
Examples: Tree, Graph, Dictionaries, Heaps, Tries, etc.
Trees
- Trees are multilevel data structures with hierarchical relationship among elements known as nodes.
- Bottommost nodes = leaf nodes; topmost node = root node.
- Each node contains pointers to adjacent nodes.
- Based on parent-child relationship.
- Each node can have more than one child (except leaves); each node has at most one parent (except root).
- Many categories — binary tree, BST, AVL (discussed later in course).
Graphs
- Pictorial representation of set of elements (vertices) connected by links known as edges.
- Graph is different from tree: graph can have cycle while tree cannot have cycle.
Way 1 By Nature
- Primitive — int, float, char, boolean, pointer
- Non-Primitive — Array, List, Stack, Queue, Tree, Graph
Way 2 By Arrangement
- Linear — Array, Linked List, Stack, Queue
- Non-Linear — Tree, Graph, Heap, Dictionary
Way 3 By Memory
- Static — Array (fixed at compile time)
- Dynamic — Linked List, dynamic Stack / Queue
A Difference between Primitive and Non-Primitive Data Structure
| Sr | Primitive Data Structure | Non-Primitive Data Structure |
|---|---|---|
| 1 | These are the basic or built-in data types provided directly by the programming language. | These are complex data structures created by using primitive data types. |
| 2 | They store a single value at a time (e.g. one integer, one character). | They store a collection or group of data items together. |
| 3 | Examples: int, float, char, boolean, pointer. | Examples: Array, Linked List, Stack, Queue, Tree, Graph. |
| 4 | They require less memory because only one value is stored in one variable. | They require more memory because many values are stored together. |
| 5 | Only basic arithmetic and logical operations can be performed on them. | Advanced operations like traversal, insertion, deletion, searching and sorting can be performed. |
| 6 | They are simple to understand and easy to use. | They are more complex and need special algorithms to manage data. |
| 7 | They are predefined by the language and the programmer cannot change their basic nature. | They can be designed and modified by the programmer as per requirement. |
| 8 | They are generally static in size. | They can be static (array) or dynamic (linked list, dynamic stack/queue). |
B Difference between Static and Dynamic Data Structure
| Sr | Static Data Structure | Dynamic Data Structure |
|---|---|---|
| 1 | The size of the data structure is fixed before or at compile time. | The size of the data structure can increase or decrease during program execution (run time). |
| 2 | Memory is allocated in advance when the program starts or at compile time. | Memory is allocated whenever needed using functions like malloc() or new. |
| 3 | The size cannot be changed after the data structure is created. | Elements can be added or removed and size can change any time. |
| 4 | Memory may be wasted if all locations are not used, or overflow may occur if data exceeds fixed size. | Memory is used only as required, so memory utilization is better. |
| 5 | Access is very fast because elements are stored in contiguous memory with direct index. | Access is slightly slower because we must follow pointers/links from one node to another. |
| 6 | Overflow can occur easily when the fixed size becomes full. | Overflow is rare and occurs only when the entire system memory is exhausted. |
| 7 | Examples: Array, static stack using array, static queue using array. | Examples: Linked List, dynamic stack, dynamic queue, tree. |
| 8 | Simple to implement and best when maximum data size is known in advance. | More flexible and best when amount of data is not known in advance. |
C Difference between Linear and Non-Linear Data Structure
| Sr | Linear Data Structure | Non-Linear Data Structure |
|---|---|---|
| 1 | In a linear data structure, all elements are arranged in a sequence or linear order. | In a non-linear data structure, elements are not arranged in sequence; they are connected in hierarchical or network form. |
| 2 | Elements are stored in non-hierarchical manner (one after another). | Elements are stored in hierarchical (tree) or connected (graph) manner. |
| 3 | Each element has one predecessor and one successor except the first and last element. | One element may be connected to two or more other elements. |
| 4 | All elements can be traversed in a single pass or single run. | All elements cannot be traversed in one pass; special methods like DFS or BFS are needed. |
| 5 | Memory may be contiguous (array) or linked in a single chain. | Memory is linked using multiple pointers or edges between nodes. |
| 6 | Easy to implement and understand. | Difficult to implement and manage compared to linear structures. |
| 7 | Examples: Array, Linked List, Stack, Queue. | Examples: Tree, Graph, Heap, Dictionary. |
| 8 | Used when data has natural sequential order (list, waiting line, undo history). | Used when data has parent-child relation or many-to-many connections (family tree, road map). |
3. Stack — Definition, LIFO, Overflow & Underflow
A Stack is a linear data structure. A stack is a list of elements in which an element may be inserted or deleted only at one end, called the top of the stack.
Stack principle is LIFO (Last In, First Out). The element inserted last on to the stack is deleted first from the stack. As the items can be added or removed only from the top, the last item to be added to a stack is the first item to be removed.
Real-life Examples of Stack
- Piles of plates — top plate removed first
- Deck of cards
- Stack of books, bangles on a wrist
- Undo (Ctrl+Z) in text editor
- Browser Back button history
- Function call stack in recursion
Operations on Stack
The two basic operations associated with stacks are:
- Push
- Pop
While performing push and pop operations the following tests must be conducted on the stack:
- Stack is empty or not
- Stack is full or not
Push
Push operation is used to add new elements into the stack. At the time of addition first check the stack is full or not. If the stack is full it generates an error message "stack overflow".
Pop
Pop operation is used to delete elements from the stack. At the time of deletion first check the stack is empty or not. If the stack is empty it generates an error message "stack underflow".
Overflow & Underflow
push when stack is full (top == MAX-1 or top == size-1 for array).pop / peek when stack is empty (top == -1).4. Stack Representation — Array vs Linked List
| Sr | Array Representation of Stack | Linked List Representation of Stack |
|---|---|---|
| 1 | Stack is implemented using a fixed-size array. | Stack is implemented using linked nodes where head node represents TOP. |
| 2 | Size is static/fixed at the time of creation. | Size is dynamic and can grow or shrink during execution. |
| 3 | TOP is maintained using an integer index (initially top = −1). | TOP is maintained using a pointer to the head node (initially top = NULL). |
| 4 | Push operation: increment top and store value in stack[top]. | Push operation: create new node and insert it at the beginning (head). |
| 5 | Pop operation: remove element at stack[top] and decrement top. | Pop operation: delete the head node and update top to next node. |
| 6 | Stack overflow occurs when top reaches maximum size (top == size−1). | Stack overflow occurs rarely, only when system memory is not available. |
| 7 | No extra memory is needed for pointers. | Extra memory is required for storing next pointer in each node. |
| 8 | Access is faster because of direct index and contiguous memory. | Access is slightly slower because of pointer traversal. |
| 9 | Some memory locations may remain unused (wastage of space). | Memory is used only for actual number of elements — no wastage of slots. |
| 10 | Implementation is simple and easy to understand. | Implementation is slightly more complex due to pointer manipulation. |
5. Stack Operations — Push, Pop, Peek, Display
| Operation | What it does | Condition to check first |
|---|---|---|
| push(x) | Add a new element x at the top. | Is stack full? (top >= size−1 → Overflow) |
| pop() | Remove the element from the top. | Is stack empty? (top == −1 → Underflow) |
| peek() / top() | See the top element without removing it. | Is stack empty? |
| display() | Print all elements from top to bottom. | Is stack empty? |
Algorithm — push()
Step 1: START
Step 2: if top >= size-1 then
write "Stack is Overflow"
Step 3: otherwise
3.1: read data value 'x'
3.2: top = top + 1
3.3: stack[top] = x
Step 4: END
Algorithm — pop()
Step 1: START
Step 2: if top == -1 then
write "Stack is Underflow"
Step 3: otherwise
3.1: print "deleted element" stack[top]
3.2: top = top - 1
Step 4: END
Algorithm — peek()
Step 1: START Step 2: if top == -1 then write "Stack is Empty" Step 3: otherwise print "Top element =" stack[top] (do NOT change top) Step 4: END
Algorithm — display()
Step 1: START
Step 2: if top == -1 then write "Stack is Empty"
Step 3: otherwise
3.1: print "Elements are:"
3.2: for i = top down to 0 → print stack[i]
Step 4: END
Remember (array stack): push → top = top + 1; stack[top] = x; pop → x = stack[top]; top = top - 1; empty when top == -1; full when top == MAX-1;
Push Diagram — Insert 11, 22, 33 (array size = 5)
Initially top = −1 (stack empty). On each push: check overflow → top = top + 1 → stack[top] = value. Element is always added at the TOP end.
Pop Diagram — Delete 33, 22, 11
On pop: check underflow → remove element at stack[top] → top = top − 1. Last inserted element is removed first (LIFO).
Push / Pop with Example (Exam Write-up — Questions.txt style)
Array stack of size 5, initially top = −1.
| Step | Operation | Action | Stack (bottom → top) | top |
|---|---|---|---|---|
| 1 | push(10) | top=0; stack[0]=10 | TOP 10 | 0 |
| 2 | push(20) | top=1; stack[1]=20 | TOP 1020 | 1 |
| 3 | push(30) | top=2; stack[2]=30 | TOP 102030 | 2 |
| 4 | peek() | returns 30 (top unchanged) | TOP 102030 | 2 |
| 5 | pop() | delete 30; top=1 | TOP 1020 | 1 |
| 6 | pop() | delete 20; top=0 | TOP 10 | 0 |
Underflow example: If top=−1, pop() → Underflow.
6. Applications of Stack
As per syllabus, main stack applications for exam are:
- Conversion of Polish notations — Infix to Postfix using stack
- Evaluation of postfix expressions — scan expression and use stack to compute result
Other common applications (extra viva):
- Recursive function calls (function call stack — LIFO of return addresses)
- Balanced parentheses checking in compilers
- Reversing a string / number using stack
- Undo / Redo in text editors
7. Polish Notations — Infix, Postfix, Prefix
+AB) is called Polish notation and Postfix (AB+) is called Reverse Polish notation. Named after Polish mathematician Jan Łukasiewicz.| Expression Type | Operator Position | Syntax | Example (A + B) | Example (A + B * C) |
|---|---|---|---|---|
| Infix | Between operands | op1 operator op2 | A + B | A + B * C |
| Postfix (Reverse Polish) | After operands | op1 op2 operator | A B + | ABC*+ |
| Prefix (Polish) | Before operands | operator op1 op2 | + A B | +A*BC |
Difference between Infix, Postfix and Prefix Notation
| Sr | Infix Expression | Postfix Expression | Prefix Expression |
|---|---|---|---|
| 1 | Operator is written between the operands. | Operator is written after the operands. | Operator is written before the operands. |
| 2 | Syntax: operand1 operator operand2 | Syntax: operand1 operand2 operator | Syntax: operator operand1 operand2 |
| 3 | Example: A + B | Example: A B + | Example: + A B |
| 4 | Example: A + B * C | Example: A B C * + | Example: + A * B C |
| 5 | Brackets are required to change order of evaluation. | Brackets are not required; order is decided by position of operator. | Brackets are not required; order is decided by position of operator. |
| 6 | Most natural for human reading and writing. | Also called Reverse Polish Notation; easy for computer evaluation. | Also called Polish Notation; used in some compilers. |
| 7 | Evaluation needs precedence and associativity rules. | Evaluated easily using stack by scanning left to right. | Evaluated using stack by scanning right to left. |
Operator Precedence & Associativity (Must-Write Table)
| Operator | Meaning | Precedence | Associativity |
|---|---|---|---|
^ | Exponentiation | 3 (highest) | Right → Left |
* , / | Multiply, Divide | 2 | Left → Right |
+ , - | Add, Subtract | 1 (lowest) | Left → Right |
( on stack | Left parenthesis | 0 (never popped by operator) | — |
8. Conversion of Polish Notations — Infix to Postfix
Scan infix left → right. Use a stack for operators / parentheses. Write postfix to output.
Right associative (^): pop while precedence(TOP) > precedence(scanned) — equal ^ does NOT pop
Complete Algorithm
- Initialize empty stack and empty output string.
- Scan the infix expression from left to right, one symbol at a time.
- If symbol is an operand (A–Z / 0–9) → append it to output.
- If symbol is ( → PUSH onto stack.
- If symbol is ) → POP and append to output until
(is popped (discard(). - If symbol is an operator:
- Case 1 — Left associative (+ − * /): while stack not empty and TOP is operator and precedence(TOP) ≥ precedence(scanned) → POP to output. Then PUSH scanned.
- Case 2 — Right associative (^): while stack not empty and TOP is operator and precedence(TOP) > precedence(scanned) → POP to output. Then PUSH scanned. (Equal ^ does NOT pop.)
- After whole expression is scanned → POP and append all remaining operators from stack.
- Output string is the postfix expression.
Decision Tree (Quick Reference)
Is scanned operator precedence > stack top?
├── YES → PUSH directly
└── NO → Is precedence equal?
├── YES → Is operator right associative?
│ ├── YES (^) → PUSH (Cases 7, 8)
│ └── NO (Left) → POP then PUSH (Cases 5, 6)
└── NO → POP then check again (Cases 2, 3, 4)
Memory: Higher wins | Left pops equal | Right stacks equal
8 Important Cases (Infix → Postfix)
| Case | Meaning | Stack TOP | Scanned | Action | Result Stack |
|---|---|---|---|---|---|
| 1 | Lower precedence in stack | + | * | Push(*) | TOP +* |
| 2 | Greater precedence in stack | * | + | Pop(*), Push(+) | TOP + |
| 3 | Greater precedence (two ops) | *, / | + | Pop /, Pop *, Push + | TOP + |
| 4 | Greater + equal (left) | +, / | + | Pop /, Pop +, Push + | TOP + |
| 5 | Equal precedence Left | * | * | Pop(*), Push(*) | TOP * |
| 6 | Equal Left (two ops) | *, / | * | Pop /, Pop *, Push * | TOP * |
| 7 | Equal Right (^) | ^ | ^ | Push(^) — no pop | TOP ^^ |
| 8 | Equal Right (many ^) | ^, ^ | ^ | Push(^) — no pop | TOP ^^^ |
Right associative (^): do NOT pop for equal precedence — just push.
Worked Example — ((A - (B + C)) * D) ^ (E + F)
Infix: ((A - (B + C)) * D) ^ (E + F) | Postfix: ABC+-D*EF+^
| SYMBOL | POSTFIX STRING | STACK | REMARKS |
|---|---|---|---|
| ( | TOP ( | Push ( | |
| ( | TOP (( | Push ( | |
| A | A | TOP (( | Operand → output |
| - | A | TOP ((- | Push - |
| ( | A | TOP ((-( | Push ( |
| B | AB | TOP ((-( | Operand |
| + | AB | TOP ((-(+ | Push + |
| C | ABC | TOP ((-(+ | Operand |
| ) | ABC+ | TOP ((- | Pop till ( |
| ) | ABC+- | TOP ( | Pop till ( |
| * | ABC+- | TOP (* | Push * |
| D | ABC+-D | TOP (* | Operand |
| ) | ABC+-D* | ∅ | Pop * |
| ^ | ABC+-D* | TOP ^ | Push ^ (right assoc.) |
| ( | ABC+-D* | TOP ^( | Push ( |
| E | ABC+-D*E | TOP ^( | Operand |
| + | ABC+-D*E | TOP ^(+ | Push + |
| F | ABC+-D*EF | TOP ^(+ | Operand |
| ) | ABC+-D*EF+ | TOP ^ | Pop + |
| End of string | ABC+-D*EF+^ | ∅ | Pop remaining ^. Input empty. |
Worked Example — a + b * c + (d * e + f) * g
Postfix: abc*+de*f+g*+
| SYMBOL | POSTFIX STRING | STACK | REMARKS |
|---|---|---|---|
| a | a | ∅ | |
| + | a | TOP + | |
| b | ab | TOP + | |
| * | ab | TOP +* | |
| c | abc | TOP +* | |
| + | abc*+ | TOP + | Pop * then push + |
| ( | abc*+ | TOP +( | |
| d | abc*+d | TOP +( | |
| * | abc*+d | TOP +(* | |
| e | abc*+de | TOP +(* | |
| + | abc*+de* | TOP +(+ | |
| f | abc*+de*f | TOP +(+ | |
| ) | abc*+de*f+ | TOP + | |
| * | abc*+de*f+ | TOP +* | |
| g | abc*+de*f+g | TOP +* | |
| End of string | abc*+de*f+g*+ | ∅ | Pop * then + |
Worked Example — A + B * C - D / E * H
Postfix: ABC*+DE/H*-
| SYMBOL | POSTFIX STRING | STACK | REMARKS |
|---|---|---|---|
| A | A | ∅ | |
| + | A | TOP + | |
| B | AB | TOP + | |
| * | AB | TOP +* | |
| C | ABC | TOP +* | |
| - | ABC*+ | TOP - | |
| D | ABC*+D | TOP - | |
| / | ABC*+D | TOP -/ | |
| E | ABC*+DE | TOP -/ | |
| * | ABC*+DE/ | TOP -* | |
| H | ABC*+DE/H | TOP -* | |
| End of string | ABC*+DE/H*- | ∅ |
Worked Example — A+(B*C-(D/E^F)*G)*H
Postfix: ABC*DEF^/G*-H*+
| SYMBOL | POSTFIX STRING | STACK | REMARKS |
|---|---|---|---|
| A | A | ∅ | |
| + | A | TOP + | |
| ( | A | TOP +( | |
| B | AB | TOP +( | |
| * | AB | TOP +(* | |
| C | ABC | TOP +(* | |
| - | ABC* | TOP +(- | |
| ( | ABC* | TOP +(-( | |
| D | ABC*D | TOP +(-( | |
| / | ABC*D | TOP +(-(/ | |
| E | ABC*DE | TOP +(-(/ | |
| ^ | ABC*DE | TOP +(-(/^ | Right assoc. — push ^ |
| F | ABC*DEF | TOP +(-(/^ | |
| ) | ABC*DEF^/ | TOP +(- | |
| * | ABC*DEF^/ | TOP +(-* | |
| G | ABC*DEF^/G | TOP +(-* | |
| ) | ABC*DEF^/G*- | TOP + | |
| * | ABC*DEF^/G*- | TOP +* | |
| H | ABC*DEF^/G*-H | TOP +* | |
| End of string | ABC*DEF^/G*-H*+ | ∅ |
9. Evaluation of Postfix Expressions
Postfix expression is evaluated easily by using a stack. Scan the expression from left to right. No operator precedence rules are needed in postfix.
Algorithm — Evaluation of Postfix Expression
Step 1: START
Step 2: Create an empty stack
Step 3: Scan the postfix expression from LEFT to RIGHT, one symbol at a time
Step 4: If scanned symbol is an OPERAND (number)
PUSH it onto the stack
Step 5: If scanned symbol is an OPERATOR
b = POP() /* first pop = RIGHT operand */
a = POP() /* second pop = LEFT operand */
result = a operator b
PUSH result onto stack
Step 6: Repeat Step 3 until end of expression
Step 7: POP the stack — this is the FINAL ANSWER
Step 8: END
− and /, compute a − b and a ÷ b where a = second pop (left) and b = first pop (right). Example: stack [8, 2], operator / → a=8, b=2 → answer = 4 (not 0).Example 1 — 2 3 4 * + → Answer: 14
Same as infix 2 + 3 * 4
| Symbol | Action | Stack |
|---|---|---|
| 2 | Push 2 | TOP 2 |
| 3 | Push 3 | TOP 23 |
| 4 | Push 4 | TOP 234 |
| * | b=4, a=3 → 3×4=12 → push 12 | TOP 212 |
| + | b=12, a=2 → 2+12=14 → push 14 | TOP 14 |
Final Answer = 14
Example 2 — 8 2 / → Answer: 4
| Symbol | Action | Stack |
|---|---|---|
| 8 | Push 8 | TOP 8 |
| 2 | Push 2 | TOP 82 |
| / | b=2, a=8 → 8÷2=4 → push 4 | TOP 4 |
Final Answer = 4
Example 3 — 5 3 + 2 * → Answer: 16
| Symbol | Action | Stack |
|---|---|---|
| 5 | Push 5 | TOP 5 |
| 3 | Push 3 | TOP 53 |
| + | b=3, a=5 → 8 | TOP 8 |
| 2 | Push 2 | TOP 82 |
| * | b=2, a=8 → 16 | TOP 16 |
Final Answer = 16
Worked Example — 6 5 2 3 + 8 * + 3 + *
| SYMBOL | OPERAND 1 | OPERAND 2 | VALUE | STACK | REMARKS |
|---|---|---|---|---|---|
| 6 | TOP 6 | Push 6 | |||
| 5 | TOP 65 | Push 5 | |||
| 2 | TOP 652 | Push 2 | |||
| 3 | TOP 6523 | First four symbols on stack | |||
| + | 2 | 3 | 5 | TOP 655 | 3+2=5 pushed |
| 8 | TOP 6558 | Push 8 | |||
| * | 5 | 8 | 40 | TOP 640 | 8*5=40 |
| + | 5 | 40 | 45 | TOP 645 | 40+5=45 |
| 3 | TOP 6453 | Push 3 | |||
| + | 45 | 3 | 48 | TOP 648 | 45+3=48 |
| * | 6 | 48 | 288 | TOP 288 | 6*48=288 — final answer |
Final Answer = 288
Worked Example — 6 2 3 + - 3 8 2 / + * 2 ^ 3 +
| SYMBOL | OPERAND 1 | OPERAND 2 | VALUE | STACK | REMARKS |
|---|---|---|---|---|---|
| 6 | TOP 6 | ||||
| 2 | TOP 62 | ||||
| 3 | TOP 623 | ||||
| + | 2 | 3 | 5 | TOP 65 | |
| - | 6 | 5 | 1 | TOP 1 | |
| 3 | TOP 13 | ||||
| 8 | TOP 138 | ||||
| 2 | TOP 1382 | ||||
| / | 8 | 2 | 4 | TOP 14 | |
| + | 3 | 4 | 7 | TOP 17 | |
| * | 1 | 7 | 7 | TOP 7 | |
| 2 | TOP 72 | ||||
| ^ | 7 | 2 | 49 | TOP 49 | |
| 3 | TOP 493 | ||||
| + | 49 | 3 | 52 | TOP 52 | Final answer |
Final Answer = 52
Stack Visualizer & Practice
Hands-on stack animation + Infix→Postfix + Postfix evaluation. Use Next Step for line-by-line trace. Zoom from top bar.
Interactive Stack Visualizer
Array: fixed size n, index top, overflow when top == n−1. Linked list: TOP → nodes with next pointers — dynamic size (demo max optional).
← scroll to see full chain →
Live memory table
| Index | stack[i] | Role |
|---|
Operation Log
top = top + 1; stack[top] = x; | pop: x = stack[top]; top = top − 1;Mobile: big buttons · try Overflow (fill stack) / Underflow (pop empty).
Infix → Postfix — Step-by-Step Animator
Follow the steps in order. Full theory is in Theory tab — this tab focuses on practice.
① Rules — Precedence & Associativity (optional reference)
Step 0 — Master this FIRST : Precedence & Associativity
Before the algorithm, you must be 100% clear on two questions: (1) Which operator works first? (Precedence) and (2) If two operators are equally strong, who goes first? (Associativity)
1 Operator Precedence = Priority (who is stronger?)
Just like BODMAS in maths — multiplication happens before addition. Higher precedence = solved first.
| Operator | Precedence (power) | Associativity | Example |
|---|---|---|---|
^ (exponent / power) | 3 — highest 🥇 | Right → Left | 2 + 3 ^ 2 → first 3^2=9 → 2+9=11 |
* / (multiply, divide) | 2 — middle 🥈 | Left → Right | 2 + 3 * 4 → first 3*4=12 → 2+12=14 |
+ − (add, subtract) | 1 — lowest 🥉 | Left → Right | 2 + 3 − 1 → same power, go left to right |
( inside the stack | 0 — weakest | — | Never popped by an operator; only ')' removes it |
2 Associativity = Direction (same power, then who first?)
Associativity is needed ONLY when two operators have EQUAL precedence. It tells the direction of solving:
⬅ LEFT associative : + − * /
Solve from LEFT to RIGHT. The operator which came earlier (left side) is solved first.
10 − 5 − 2= (10 − 5) − 2 = 5 − 2 = 3 ✔
NOT 10 − (5 − 2) = 7 ✘8 / 4 / 2= (8 / 4) / 2 = 2 / 2 = 1 ✔
NOT 8 / (4 / 2) = 4 ✘
➡ RIGHT associative : ^ only
Solve from RIGHT to LEFT. The operator which came later (right side) is solved first.
2 ^ 3 ^ 2= 2 ^ (3 ^ 2) = 2 ^ 9 = 512 ✔
NOT (2 ^ 3) ^ 2 = 8 ^ 2 = 64 ✘- That is why postfix of
A^B^CisABC^^(notAB^C^).
3 Same idea inside the STACK — Case 1 (≥ and Case 2 >
While converting, whenever you scan an operator, compare it with the operator sitting on the stack top:
| Situation (compare with stack TOP) | Decision | Why? (from the algorithm) |
|---|---|---|
Stack is empty, or top is ( | PUSH | While-loop does not run. Push scanned. |
| Top has LOWER precedence than scanned | PUSH | Neither ≥ nor > is true → no pop. Push scanned. |
| Top has HIGHER precedence than scanned | POP → output, compare again | Both Case 1 (≥ and Case 2 > are true → pop. |
EQUAL + LEFT associative (+ − * /) | POP → output, then PUSH | Case 1: ≥ is true when equal → pop. |
EQUAL + RIGHT associative (^) | PUSH only — NO pop! | Case 2: > is false when equal → no pop. |
🎯 Decision Trainer — test yourself!
Choose what is on the stack top and which operator you have scanned. See the decision and the reason instantly.
② ALGORITHM — read when ready (click to open)
Infix → Postfix : Complete Algorithm
Learn this algorithm by heart. The only hard part is the operator step — Case 1 uses ≥ (left-associative), Case 2 uses > (right-associative).
-
If it is a left parenthesis
(
→ PUSH it onto the stack. -
If it is an operand (A–Z, a–z, 0–9)
→ Add it directly to the postfix output. -
If it is a right parenthesis
)
→ Repeatedly POP operators from the stack and add them to the postfix expression.
→ Stop when a left parenthesis(is found and discard it (do not add it to the output). -
If it is an operator (e.g., +, −, ×, ÷, ^)
→ While the stack is not empty, the top is not(, and:Case 1 Left-Associative Operator (
+ − * /)precedence(top of stack) ≥ precedence(scanned operator)Equal OR higher → POP→ Then POP that operator from the stack and add it to the postfix expression (repeat while condition is true).Case 2 Right-Associative Operator (
^)precedence(top of stack) > precedence(scanned operator)Only strictly higher → POP | Equal → NO pop, just PUSH
→ Finally PUSH the scanned operator onto the stack.
③ CONCEPT LAB — Visualize the 8 Cases (most important)
8 Cases — One Formula, Clear Decision
For each case ask: TOP vs Scanned. Check the formula → YES = POP, NO = PUSH only.
Before
After (animated)
④ PRACTICE — Full expression step-by-step
Full Expression — Step-by-Step
Pick an example from the dropdown → Load → press Next Step only (manual control).
Infix (scanning)
Postfix so far
Trace Table — Stack column = actual stack
| Symbol | Stack (bottom→TOP) | Postfix Output | Remark |
|---|
⑤ C CODE — open when you want the program
C Program — Infix to Postfix Conversion
#include <stdio.h>
#include <ctype.h>
#define MAX 100
char stack[MAX];
int top = -1;
void push(char c) {
if (top < MAX - 1) {
top = top + 1;
stack[top] = c;
}
}
char pop() {
char ch = '\0';
if (top != -1) {
ch = stack[top];
top = top - 1;
}
return ch;
}
char peek() {
if (top != -1)
return stack[top];
return '\0';
}
int precedence(char op) {
if (op == '^')
return 3;
else if (op == '*' || op == '/')
return 2;
else if (op == '+' || op == '-')
return 1;
else
return 0; /* for '(' */
}
int main() {
char infix[MAX], postfix[MAX];
int i = 0, j = 0;
char ch;
printf("Enter infix expression: ");
gets(infix);
while (infix[i] != '\0') {
ch = infix[i];
if (isalnum(ch)) { /* operand → output */
postfix[j] = ch;
j = j + 1;
} else if (ch == '(') { /* '(' → push */
push(ch);
} else if (ch == ')') { /* ')' → pop till '(' */
while (top != -1 && peek() != '(') {
postfix[j] = pop();
j = j + 1;
}
pop(); /* remove '(' */
} else { /* operator */
if (ch == '^') { /* Case 2: ^ right-assoc — use > only */
while (top != -1 && peek() != '(' &&
precedence(peek()) > precedence(ch)) {
postfix[j] = pop();
j = j + 1;
}
} else { /* Case 1: + - * / left-assoc — use >= */
while (top != -1 && peek() != '(' &&
precedence(peek()) >= precedence(ch)) {
postfix[j] = pop();
j = j + 1;
}
}
push(ch);
}
i = i + 1;
}
while (top != -1) { /* pop the rest */
postfix[j] = pop();
j = j + 1;
}
postfix[j] = '\0';
printf("Postfix Expression: %s\n", postfix);
return 0;
}
A+B*C-D/E*H → Output ABC*+DE/H*-A^B^C → ABC^^ (stack TOP ^ + scanned ^ → Case 2: 3 > 3 false → NO pop, only PUSH)Evaluation of Postfix Expression (using Stack)
Good news: here you don't need precedence or associativity at all! Postfix already has the correct order built inside it. Only two rules: number → push, operator → pop two, compute, push back.
b = POP() ← first pop = SECOND operanda = POP() ← second pop = FIRST operandresult = a operator b (a first! b second!)⚠ Most important!
Order: first pop = b, second pop = a. Result = a op b, NOT b op a.
Mini dry run : 8 2 /
| Symbol | Action | Stack |
|---|---|---|
| 8 | number → push 8 | 8 |
| 2 | number → push 2 | 8, 2 |
| / | b=pop()=2, a=pop()=8 → a/b = 8/2 = 4 → push 4 | 4 |
b (right side), second popped is a (left side). Answer = a − b / a ÷ b, NOT b − a. Here 8/2 = 4 ✔, not 2/8 ✘.Mini dry run : 2 3 4 * + (infix: 2 + 3 * 4)
| Symbol | Action | Stack |
|---|---|---|
| 2 | push 2 | 2 |
| 3 | push 3 | 2, 3 |
| 4 | push 4 | 2, 3, 4 |
| * | b=4, a=3 → 3*4 = 12 → push | 2, 12 |
| + | b=12, a=2 → 2+12 = 14 → push | 14 |
Answer = 14 — exactly what BODMAS gives for 2 + 3 * 4. The stack did it automatically!
🎬 Step-by-Step Animation
Trace Table — Stack = actual stack
| Symbol | Operand 1 (a) | Operand 2 (b) | Value | Stack (bottom→TOP) |
|---|
C Program — Postfix Expression Evaluation
#include <stdio.h>
#include <ctype.h>
#define MAX 100
int stack[MAX];
int top = -1;
void push(int n) {
if (top < MAX - 1) {
top = top + 1;
stack[top] = n;
}
}
int pop() {
int x = 0;
if (top != -1) {
x = stack[top];
top = top - 1;
}
return x;
}
int main() {
char postfix[MAX];
int i = 0, a, b, result = 0, j;
printf("Enter postfix expression: ");
gets(postfix);
while (postfix[i] != '\0') {
char ch = postfix[i];
if (isdigit(ch)) {
push(ch - '0'); /* char digit → int */
} else {
b = pop(); /* first pop = b */
a = pop(); /* second pop = a */
if (ch == '+') {
result = a + b;
} else if (ch == '-') {
result = a - b;
} else if (ch == '*') {
result = a * b;
} else if (ch == '/') {
result = a / b;
} else if (ch == '^') { /* a to the power b */
result = 1;
for (j = 0; j < b; j++) {
result = result * a;
}
}
push(result);
}
i = i + 1;
}
printf("Result: %d\n", pop());
return 0;
}
6523+8*+3+* → Result 288Bonus — Prefix Expression Evaluation (scan RIGHT to LEFT)
Prefix is evaluated the same way, but we scan from right to left, and after popping: first popped = a, second popped = b.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX 100
int stack[MAX];
int top = -1;
void push(int n) {
if (top < MAX - 1) {
top = top + 1;
stack[top] = n;
}
}
int pop() {
int x = 0;
if (top != -1) {
x = stack[top];
top = top - 1;
}
return x;
}
int main() {
char prefix[MAX];
int len, i, a, b, result = 0, j;
printf("Enter prefix expression: ");
gets(prefix);
len = strlen(prefix);
i = len - 1; /* start from the END */
while (i >= 0) {
char ch = prefix[i];
if (isdigit(ch)) {
push(ch - '0');
} else {
a = pop(); /* first pop = a */
b = pop(); /* second pop = b */
if (ch == '+') result = a + b;
else if (ch == '-') result = a - b;
else if (ch == '*') result = a * b;
else if (ch == '/') result = a / b;
else if (ch == '^') {
result = 1;
for (j = 0; j < b; j++)
result = result * a;
}
push(result);
}
i = i - 1;
}
printf("Result: %d\n", pop());
return 0;
}
Theory Questions
- Distinguish between linear and non-linear data structures with suitable examples.
- Distinguish between primitive and non-primitive data structures with suitable examples.
- Distinguish between static and dynamic data structures.
- Define Stack. Explain push() and pop() with example, algorithm and diagrams.
- Explain stack overflow and stack underflow conditions.
- What are Polish and Reverse Polish notations? Why does a computer prefer postfix?
- List the applications of stack.
Practice — Infix to Postfix (try animator, tab 5)
A + B * C→ABC*+A * B + C / D→AB*CD/+A ^ B ^ C→ABC^^A + B * C - D / E * H→ABC*+DE/H*-a + b * c + (d * e + f) * g→abc*+de*f+g*+((A - (B + C)) * D) ^ (E + F)→ABC+-D*EF+^A + (B * C - (D / E ^ F) * G) * H→ABC*DEF^/G*-H*+A * B / C→AB*C/A - B + C→AB-C+(A + B) * (C - D)→AB+CD-*A + B ^ C ^ D→ABCD^^+X + Y * Z ^ W→XYZW^*+
Practice — Postfix Evaluation (try animator, tab 6)
6 5 2 3 + 8 * + 3 + *→2886 2 3 + - 3 8 2 / + * 2 ^ 3 +→522 3 1 * + 9 -→-45 3 + 8 2 - *→482 3 4 * +→149 5 + 2 *→287 2 ^→494 5 * 3 2 + /→43 4 + 2 * 7 /→25 5 + 2 ^→100
Program List (see Programs tab)
- Stack Using Array
- Stack Using Linked List
- Reverse a Number using Stack
- Reverse a String using Stack
- Check Palindrome using Stack (String)
- Check if Number of 'a's Equals Number of 'b's
- Check for Balanced Parentheses in an Expression
- Armstrong Number using Stack
- Copy Stack to Another Stack
- Sort a Stack using Another Stack
- Infix to Postfix Conversion
- Infix to Prefix Conversion
- Postfix Expression Evaluation
- Prefix Expression Evaluation
1. Reverse a Number
Push each digit, then pop to reverse (LIFO).
| Step | Line | Stack | Out |
|---|
Real-Life Stack Projects
Advanced problem statements with sample & hidden test cases, full C solution, and step-by-step stack trace. Like a mini coding platform for Unit I.
P1. Undo Text Editor
Input / Output Format
Sample Test Cases (visible)
Hidden Test Cases 🔒
Inputs are hidden — like online judge. Run your logic via trace or check against expected output.
How to Solve (Steps)
Your Input (try a test case)
Quick samples:
| Step | Line | Stack | Note |
|---|