0% found this document useful (0 votes)
4 views32 pages

Ds Complete Notes

The document provides comprehensive study notes on data structures, covering fundamental concepts, algorithm analysis, time and space complexity, and various data structures like stacks, queues, linked lists, and trees. It emphasizes the importance of choosing the right data structure for efficient performance and includes detailed explanations of operations, complexities, and applications. Additionally, it discusses algorithm design steps and techniques for searching and expression evaluation.

Uploaded by

amaangd22
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views32 pages

Ds Complete Notes

The document provides comprehensive study notes on data structures, covering fundamental concepts, algorithm analysis, time and space complexity, and various data structures like stacks, queues, linked lists, and trees. It emphasizes the importance of choosing the right data structure for efficient performance and includes detailed explanations of operations, complexities, and applications. Additionally, it discusses algorithm design steps and techniques for searching and expression evaluation.

Uploaded by

amaangd22
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

DATA STRUCTURES -

COMPLETE STUDY NOTES


[Link] 3rd Semester (PCC-CSE-221-G)

UNIT-I: FUNDAMENTALS & ALGORITHM


ANALYSIS
1. BASIC CONCEPTS
Data Structure Definition

Organized collection of data with a set of operations


Comprises: Data values + Operations + Axioms
Examples: Arrays, Linked Lists, Stacks, Queues, Trees, Graphs

Why Study Data Structures?

Choose right structure for problem → Better performance


Reduces time complexity → Faster programs
Reduces space complexity → Efficient memory use
Key to writing scalable software

Algorithm Definition

Finite sequence of steps to solve a problem


Characteristics: Input, Process, Finiteness, Effectiveness, Output
Must be: Simple, Unambiguous, Effective, Finite, Efficient

2. BIG-O NOTATION & COMPLEXITY ANALYSIS


Big-O Definition

T(n) = O(g(n)) if ∃ constants c > 0, n₀ such that:

T(n) ≤ c × g(n) for all n ≥ n₀


Measures upper bound on growth rate
Ignores constants and lower-order terms
Helps compare algorithms on large inputs

Complexity Classes (Best to Worst)

O(1) < O(log n) < O(n) < O(n log n) < O(n²) < O(n³) < O(2ⁿ) < O(n!)

Common Big-O Classes


Class Name Example Use Case
O(1) Constant Array access arr[i] Hash tables, Direct access
O(log n) Logarithmic Binary search Searching sorted data
O(n) Linear Linear search, Traversal Simple loops
O(n log n) Linear log Merge sort, Quick sort Efficient sorting
O(n²) Quadratic Bubble sort, Nested loops Small datasets
O(n³) Cubic Matrix multiplication Avoid if possible
O(2ⁿ) Exponential Naive Fibonacci AVOID - exponential growth
O(n!) Factorial All permutations DEFINITELY AVOID

Calculating Big-O

Rule 1: Count loops

Single loop: O(n)


Nested loops: Multiply → O(n²), O(n³)
Sequential: Add → Take larger

Rule 2: Drop constants

O(2n) → O(n)
O(5n²) → O(n²)

Rule 3: Drop lower-order terms

O(n² + n) → O(n²)
O(n log n + n) → O(n log n)

Rule 4: Recursion

Use recursion tree or count function calls

Other Asymptotic Notations

Ω (Omega): Lower bound - at least this time


Θ (Theta): Tight bound - exactly this time
o (little-o): Strict upper bound - strictly faster
3. TIME COMPLEXITY
Definition

Amount of time algorithm needs to run to completion

Why Study?

Know if program will respond in time (real-time systems)


Compare multiple solutions
Predict performance on large data

Measuring Time Complexity

Count key operations (operations taking max time)


Time complexity = f(number of key operations)

Cases

Best Case: Minimum time (rare, minimum input)


Average Case: Realistic scenario
Worst Case: Maximum time (what we use for Big-O)

Examples

Linear Search:
- Best: O(1) - found at first position
- Worst: O(n) - found at last position or not found
- Average: O(n/2) ≈ O(n)

Binary Search:
- All cases: O(log n)

4. SPACE COMPLEXITY
Definition

Amount of memory program needs to run to completion

Components

1. Instruction Space: Fixed - space for executable code


2. Data Space:
Constants & variables: Fixed
Arrays & structures: Fixed or variable
Dynamic allocation: Variable
3. Stack Space: For function calls and recursion

Calculation

Total Space = Fixed Space + Variable Space

Examples

Array of size n:
Space = O(n) + O(1) = O(n)

2D Array n×n:
Space = O(n²)

Recursive function depth d:


Stack space = O(d)

Space vs Time Tradeoff

More time: Less memory needed


Less time: More memory needed
Choose based on constraints

5. CHOOSING THE RIGHT DATA STRUCTURE


Criteria

1. Problem requirements - What operations needed?


2. Frequency of operations - Which are most common?
3. Size of data - Fixed or dynamic?
4. Time constraints - How fast must it be?
5. Space constraints - How much memory available?

Comparison Example - Student Records

Poor Choice - Parallel Arrays:


char nameList[60][15]; // 60 students, 15 char names
int roll[60];
int marks[60];
float percent[60];
char grade[60];
// Swapping 2 students needs 15 separate statements

Good Choice - Array of Structures:

struct student {
char name[15];
int roll;
int marks;
float percent;
char grade;
};
struct student studList[60];
// Swapping only 3 statements

6. ARRAY vs LINKED LIST


Memory Layout

Array: Contiguous memory locations [sequential]


Linked List: Scattered memory with pointers

Access Time

Array: O(1) - direct access arr[5]


Linked List: O(n) - must traverse from start

Insertion/Deletion

Array: O(n) - need to shift elements


Linked List: O(1) - only change pointers

Memory Efficiency

Array: No extra memory


Linked List: Extra memory for pointers

When to Use

Array: Frequent access, fixed size


Linked List: Frequent insertion/deletion, dynamic size

7. SEARCHING TECHNIQUES
Linear Search - O(n)

int linear_search(int arr[], int n, int target) {


for (int i = 0; i < n; i++) {
if (arr[i] == target) return i;
}
return -1;
}

Works on unsorted data


Simple but slow
Worst case: Check all elements

Binary Search - O(log n)

int binary_search(int arr[], int n, int target) {


int left = 0, right = n - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] == target) return mid;
else if (arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}

Requires sorted array


Divide and conquer
50,000x faster than linear for 1M elements!

8. ALGORITHM DESIGN STEPS


Step 1: Understand Problem

What are inputs and outputs?


What constraints exist?
What is acceptable performance?
Step 2: Identify Inputs & Outputs

Input data type and size


Output format required

Step 3: Choose Data Structure

Which structure suits problem?


Trade-offs between options?

Step 4: Design Logic

Write algorithm in simple English


Pseudocode or flowchart
Verify correctness

Step 5: Test Algorithm

Test with various inputs


Check edge cases
Verify correctness

Step 6: Refine Until Perfect

Optimize if needed
Improve readability
Add comments

UNIT-II: STACKS & QUEUES


1. STACK - LIFO (Last In First Out)
Definition

Linear data structure where insertion & deletion happen at same end (top)

Operations

PUSH: Insert element on top - O(1)


POP: Remove element from top - O(1)
PEEK/TOP: View top element - O(1)
isEmpty: Check if empty - O(1)

Stack Implementation
#define MAX 100
struct stack {
int data[MAX];
int top;
};

void push(struct stack *s, int x) {


if (s->top == MAX - 1) { printf("Overflow\n"); }
else { s->data[++s->top] = x; }
}

int pop(struct stack *s) {


if (s->top == -1) { printf("Underflow\n"); return -1; }
return s->data[s->top--];
}

Applications of Stack

1. Function Calls & Recursion

Save return address


Store local variables
Stack frames for each call

2. Expression Evaluation

Infix to postfix conversion


Evaluate postfix expressions
Operator precedence handling

3. String Reversal

Push characters, pop to reverse

4. Backtracking

Maze solving
Puzzle solving
DFS traversal

5. Undo/Redo

Text editors store operations

6. Parentheses Matching

Compiler syntax checking


7. Memory Management

Call stack for function execution

Key Points

LIFO order: Last pushed is first popped


Used in compilers and OS
Elegant solution for recursive problems
Limited size (fixed array) or dynamic (linked list)

2. QUEUE - FIFO (First In First Out)


Definition

Linear data structure where insertion at rear, deletion at front

Operations

ENQUEUE: Insert at rear - O(1)


DEQUEUE: Remove from front - O(1)
PEEK: View front element - O(1)
isEmpty: Check if empty - O(1)

Simple Queue
struct queue {
int data[MAX];
int front, rear;
};

void enqueue(struct queue *q, int x) {


if (q->rear == MAX - 1) { printf("Overflow\n"); }
else {
if (q->front == -1) q->front = 0;
q->data[++q->rear] = x;
}
}

int dequeue(struct queue *q) {


if (q->front == -1) { printf("Underflow\n"); return -1; }
int x = q->data[q->front];
if (q->front == q->rear) q->front = q->rear = -1;
else q->front++;
return x;
}

Problem: Linear Queue Wastes Space

After dequeuing, front positions become unused


Can't reuse even if space available

3. CIRCULAR QUEUE - O(1) Operations


Definition

Queue where rear wraps around to front, forming circle

Advantages

1. Memory Reuse - Deleted positions used by new elements


2. No Wastage - Uses all allocated space
3. Efficient - O(1) for all operations
4. Solves rebuffering problem - No shifting needed

Difference from Linear Queue

Linear: Rear at end → can't insert even if front vacant


Circular: Rear wraps around → can insert if space available
Circular Queue Operations

Insert (Enqueue):

1. Check if full: (rear + 1) mod n == front


2. If empty: front = 0, rear = 0
3. Else: rear = (rear + 1) mod n
4. Insert at position rear

Delete (Dequeue):

1. Check if empty: front == rear


2. Delete element at front
3. If queue now empty: front = 0, rear = 0
4. Else: front = (front + 1) mod n

Circular Queue Array Layout

Position: 0 1 2 3 4 5 6 7
Before: 5 6 . . . 1 2 3
└──────rear front────┘

After insert 7:
5 6 7 . . 1 2 3 (wraps around!)

4. PRIORITY QUEUE
Definition

Ordered collection where service based on priority, not FIFO

Difference from Normal Queue

Queue: First come, first served (FIFO)


Priority Queue: Higher priority served first

Real-World Example

Hospital emergency room:

Critical patient → Served immediately


Minor injury → Served later
Implementation Methods

Method 1: Sorted List

Insertion: Complex O(n) - find correct position


Deletion: Simple O(1) - remove from front

Method 2: FIFO List + Priority Check

Insertion: Simple O(1) - add at rear


Deletion: Complex O(n) - search for highest priority

Applications

1. Operating Systems

CPU scheduling
Process priority
Interrupt handling

2. Networking

Packet routing
QoS (Quality of Service)

3. Algorithms

Dijkstra's shortest path


A* search (AI)

4. Data Compression

Huffman coding

5. Event Simulation

Customer service simulation

6. Game Development

Task scheduling

5. DEQUE (Double Ended Queue)


Definition

Queue with insertion & deletion at both ends

Types
1. Input Restricted: Insert at one end, delete from both
2. Output Restricted: Delete from one end, insert from both

Properties

More flexible than queue or stack


Can be used as both stack and queue
Applications: Palindrome checking, sliding window

Time Complexity

Insert at front/rear: O(1)


Delete from front/rear: O(1)

6. EXPRESSION CONVERSION & EVALUATION


Notations

Infix: A + B (human readable)


Prefix: + A B (operator before operands)
Postfix: A B + (operator after operands)

Why Conversion?

Postfix eliminates need for parentheses


Easier for computers to evaluate
No operator precedence issues

Postfix Evaluation (Stack-based)

Algorithm:
1. Scan postfix expression left to right
2. If operand: push to stack
3. If operator: pop 2 operands, apply operation, push result
4. Final result in stack

**Example: 5 3 + 2 ***

Step 1: Push 5 → Stack: [5]


Step 2: Push 3 → Stack: [5, 3]
Step 3: See + → Pop 3, 5 → Compute 5+3=8 → Push 8 → Stack: [8]
Step 4: Push 2 → Stack: [8, 2]
Step 5: See * → Pop 2, 8 → Compute 8*2=16 → Push 16 → Stack: [16]
Result: 16
UNIT-III: LINKED LISTS & TREES
1. LINKED LIST FUNDAMENTALS
Definition

Dynamic data structure with nodes containing data and pointers

Node Structure

struct node {
int data; // Data element
struct node *next; // Pointer to next node
};

Advantages over Array

Dynamic size
Easy insertion/deletion: O(1)
No wastage of memory

Disadvantages

Sequential access: O(n)


Extra memory for pointers
Cache performance worse

2. SINGLY LINKED LIST


Structure

head → [data|next] → [data|next] → [data|next] → NULL

Key Operations

Traversal - O(n):
void traverse(struct node *head) {
while (head != NULL) {
printf("%d ", head->data);
head = head->next;
}
}

Insertion at Beginning - O(1):

struct node* insert_begin(struct node *head, int data) {


struct node *new = (struct node*)malloc(sizeof(struct node));
new->data = data;
new->next = head;
return new; // New node is new head
}

Insertion at Position - O(n):

void insert_pos(struct node *head, int data, int pos) {


struct node *new = (struct node*)malloc(sizeof(struct node));
new->data = data;

struct node *curr = head;


for (int i = 1; i < pos - 1; i++) {
curr = curr->next;
}
new->next = curr->next;
curr->next = new;
}

Deletion - O(n):
struct node* delete_node(struct node *head, int data) {
if (head->data == data) {
struct node *temp = head;
head = head->next;
free(temp);
return head;
}

struct node *curr = head;


while (curr->next != NULL) {
if (curr->next->data == data) {
struct node *temp = curr->next;
curr->next = temp->next;
free(temp);
break;
}
curr = curr->next;
}
return head;
}

Searching - O(n):

struct node* search(struct node *head, int target) {


while (head != NULL) {
if (head->data == target) return head;
head = head->next;
}
return NULL;
}

3. DOUBLY LINKED LIST


Structure

struct node {
int data;
struct node *prev; // Pointer to previous
struct node *next; // Pointer to next
};
Graphical Layout

NULL ← [data|prev|next] ↔ [data|prev|next] ↔ [data|prev|next] → NULL

Advantages

Can traverse both directions


Easier deletion (have prev pointer)
Better for certain operations

Disadvantages

Extra memory for prev pointer


More complex implementation

Key Difference from Singly

Singly: Can only go forward


Doubly: Can go forward AND backward

4. CIRCULAR LINKED LIST


Definition

Last node points back to first node instead of NULL

Structure

start → [data|next] → [data|next] → [data|next] ↓


↑_______________________________________↑
(wraps around to form circle)

Advantages

1. Each node accessible from any node


2. No special handling for first node
3. Can traverse from any starting point
4. Every node has predecessor

Disadvantages

1. Risk of infinite loop if not careful


2. No NULL pointer to detect end
3. More complex than singly linked list
Characteristic Feature

last_node->next == first_node; // Not NULL!

5. BINARY TREE
Definition

Finite set of nodes which is either empty OR


Consists of root and two disjoint binary subtrees (left & right)
Each node has degree ≤ 2

Node Structure

struct node {
int data;
struct node *left; // Left subtree pointer
struct node *right; // Right subtree pointer
};

Tree Terminology

Root: Top node with no parent


Parent: Node with children
Child: Node with parent
Leaf: Node with no children
Height: Longest path from root to leaf
Depth: Distance from root
Siblings: Nodes with same parent
Subtree: Tree formed by node and descendants

Example Tree

1 (Root, Height=2)
/ \
2 3
/ \
4 5 (Leaf nodes: 4, 5, 3)

Types of Binary Trees

1. Full Binary Tree: Every node has 0 or 2 children


2. Complete Binary Tree: All levels full except possibly last
3. Perfect Binary Tree: All leaves at same level
4. Balanced Binary Tree: Height difference ≤ 1
5. Skewed Tree: Linear structure (worst case)

6. BINARY SEARCH TREE (BST)


Definition

Binary tree with ordering property:

Left subtree values < Root value


Right subtree values > Root value
Both subtrees are also BSTs

Example

20
/ \
10 30
/ \ / \
5 15 25 35

Properties

In-order traversal gives sorted sequence


Average search: O(log n)
Worst case search: O(n) if unbalanced
Insertion/Deletion: O(log n) average

Operations

Search - O(log n) average:

struct node* search(struct node *root, int target) {


if (root == NULL) return NULL;
if (root->data == target) return root;
if (target < root->data) return search(root->left, target);
else return search(root->right, target);
}

Insertion - O(log n) average:


struct node* insert(struct node *root, int data) {
if (root == NULL) {
struct node *new = malloc(sizeof(struct node));
new->data = data;
new->left = new->right = NULL;
return new;
}
if (data < root->data) root->left = insert(root->left, data);
else root->right = insert(root->right, data);
return root;
}

Applications

Database indexing
Symbol table in compilers
File system directories
Autocomplete/Spell checking
Range searching

Worst Case - Unbalanced BST

If input: 1, 2, 3, 4, 5 (sorted)
Results in:
1
\
2
\
3 (Like a linked list!)
\
4
\
5
Search becomes O(n) - AVOID!
Solution: Use AVL Trees or Red-Black Trees

7. TREE TRAVERSALS
Why Traverse?

Visit every node in tree in systematic order


Types

1. Inorder (Left-Root-Right):

Algorithm:
1. Traverse left subtree
2. Process root
3. Traverse right subtree

For BST → Gives SORTED order!

2. Preorder (Root-Left-Right):

Algorithm:
1. Process root
2. Traverse left subtree
3. Traverse right subtree

Use: Create copy of tree, Prefix notation

3. Postorder (Left-Right-Root):

Algorithm:
1. Traverse left subtree
2. Traverse right subtree
3. Process root

Use: Delete tree, Postfix notation

Example - Tree Traversals

Tree: 1
/ \
2 3
/ \
4 5

Inorder: 4 2 5 1 3
Preorder: 1 2 4 5 3
Postorder: 4 5 2 3 1

Level-Order (Breadth-First)
Process nodes level by level:
Level 0: 1
Level 1: 2, 3
Level 2: 4, 5

Output: 1 2 3 4 5

8. AVL TREE (Balanced BST)


Definition

Binary search tree that maintains balance to ensure O(log n) operations

Balance Property

|Height(left) - Height(right)| ≤ 1

Why AVL?

BST worst case: O(n) if unbalanced


AVL guarantees: O(log n) always
Uses rotations to maintain balance

Balance Factor

BF = Height(left) - Height(right)
BF must be -1, 0, or +1

Self-Balancing Property

When BF becomes ±2, rotations performed:

Single rotation (LL or RR case)


Double rotation (LR or RL case)

Applications

Database indexing
File systems
Memory allocation

9. APPLICATIONS OF BINARY TREES


1. Expression Trees - Mathematical expressions in compilers
2. Huffman Coding - Data compression algorithm
3. Heaps - Priority queues, heap sort
4. Binary Search Trees - Searching, indexing
5. Trie Trees - Autocomplete, spell checking
6. Game Trees - Minimax algorithm, game AI
7. Segment Trees - Range queries
8. Merkle Trees - Blockchain, verification
9. Spreadsheets - Microsoft Excel data structure
10. Memory Allocation - OS memory management
11. Syntax Trees - Compiler parsing
12. Network Routing - Binary trees for routing decisions

UNIT-IV: SORTING ALGORITHMS


1. SORTING FUNDAMENTALS
Definition

Arranging elements in increasing or decreasing order

Types

Internal Sorting: In primary memory (RAM)


External Sorting: From secondary memory (Files)

Properties of Good Sorting Algorithm

1. Adaptive: O(n) when data nearly sorted


2. Stable: Equal elements maintain relative order
3. In-place: O(1) extra space needed
4. Online: Can sort while receiving data
5. Efficient: Minimizes comparisons and swaps

Comparison Complexity

For any comparison-based sort:

Minimum: Ω(n log n)


Cannot do better than O(n log n)

2. BUBBLE SORT - O(n²)


Algorithm
flag = false
while flag == false:
flag = true
for j = 0 to n-2:
if list[j] > list[j+1]:
swap(list[j], list[j+1])
flag = false

How It Works

Compares adjacent elements


Swaps if in wrong order
Largest element "bubbles up" to end
Repeats until sorted

Example Trace

Initial: 5 3 8 4 2
Pass 1: 3 5 4 2 8 (8 in position)
Pass 2: 3 4 2 5 8 (5 in position)
Pass 3: 2 3 4 5 8 (sorted)

Complexity

Best: O(n) - already sorted


Average: O(n²)
Worst: O(n²) - reverse sorted
Space: O(1)
Stable: Yes
Adaptive: Yes

Code
void bubble_sort(int arr[], int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}

3. INSERTION SORT - O(n²)


Algorithm

for i = 1 to n-1:
key = arr[i]
j = i - 1
while j >= 0 and arr[j] > key:
arr[j+1] = arr[j]
j = j - 1
arr[j+1] = key

How It Works

Builds sorted array one element at a time


Takes each element and inserts in correct position
Like sorting playing cards

Example Trace

Initial: 5 3 8 4 2
Pass 1: 3 5 8 4 2
Pass 2: 3 5 8 4 2
Pass 3: 3 4 5 8 2
Pass 4: 2 3 4 5 8

Complexity

Best: O(n) - already sorted


Average: O(n²)
Worst: O(n²)
Space: O(1)
Stable: Yes
Adaptive: Yes

Advantages

Simple to implement
Efficient for small datasets
Efficient for nearly sorted data
Online sorting (sort while receiving data)

4. QUICK SORT - O(n log n) average


Algorithm

partition(low, high):
Choose pivot
Arrange pivot in correct position
Elements < pivot on left
Elements > pivot on right
Return partition index

quicksort(low, high):
if low < high:
pi = partition(low, high)
quicksort(low, pi-1)
quicksort(pi+1, high)

How It Works

Divide and conquer


Partition around pivot
Recursively sort sublists

Pivot Selection Strategies

1. First element - Simple but risky


2. Last element - Better
3. Middle element - Good
4. Median-of-three - Best for random data
5. Random - Avoids worst case

Example
Original: 8 5 9 2 1 7 6

Choose pivot = 7:
Left < 7: 5 2 1 6
Pivot: 7
Right > 7: 8 9

Recursively sort:
Left: 1 2 5 6
Right: 8 9

Result: 1 2 5 6 7 8 9

Complexity

Best: O(n log n) - balanced partitions


Average: O(n log n)
Worst: O(n²) - pivot always smallest/largest
Space: O(log n) - recursion stack
Stable: No
Adaptive: No

Advantages

Very fast average case


In-place sorting
Cache efficient
Most commonly used

Disadvantages

Worst case O(n²)


Not stable
Requires careful pivot selection

5. MERGE SORT - O(n log n) guaranteed


Algorithm
mergesort(left, right):
if left < right:
mid = (left + right) / 2
mergesort(left, mid)
mergesort(mid+1, right)
merge(left, mid, right)

merge(left, mid, right):


Compare elements from two halves
Place smaller in temporary array
Copy remaining elements

How It Works

Divide array into two halves


Recursively sort each half
Merge two sorted halves

Example

Original: 8 5 9 2 1 7 6 4

Divide: [8 5 9 2] [1 7 6 4]
[8 5][9 2] [1 7][6 4]
[8][5][9][2] [1][7][6][4]

Merge: [5 8][2 9] [1 7][4 6]


[2 5 8 9] [1 4 6 7]
[1 2 4 5 6 7 8 9]

Complexity

All cases: O(n log n) - GUARANTEED!


Space: O(n) - needs temporary array
Stable: Yes
Adaptive: No

Advantages

Guaranteed O(n log n)


Stable sorting
Good for linked lists
Predictable performance
Disadvantages

Requires extra O(n) space


Slower than quick sort on average (more data movement)
Not in-place

6. HEAP SORT - O(n log n)


Algorithm

heapsort(arr, n):
Build max heap from array
for i = n-1 to 0:
Swap arr[0] with arr[i] (move largest to end)
Heapify root with heap size i-1

How It Works

Build max heap (largest at top)


Extract max element (place at end)
Reorganize remaining heap
Repeat until heap empty

Heap Properties

Parent at index i
Left child at 2i+1
Right child at 2i+2
Parent >= children (max heap)

Example
Original: [25, 13, 17, 5, 8, 3]

Build heap: 25
/ \
13 17
/ \ /
5 8 3

Heap array: [25, 13, 17, 5, 8, 3]

Extract 25: [3, 13, 17, 5, 8] | 25


Heapify: [17, 13, 3, 5, 8] | 25

Extract 17: [8, 13, 3, 5] | 17, 25


...continue...

Final: [3, 5, 8, 13, 17, 25]

Complexity

All cases: O(n log n)


Space: O(1) - in-place
Stable: No
Adaptive: No

Advantages

Guaranteed O(n log n)


In-place (no extra space)
Good for memory-constrained systems

Disadvantages

Slower than quick sort on average


Not stable
More complex to implement

7. SORTING ALGORITHMS COMPARISON TABLE


Algorithm Best Average Worst Space Stable In-Place Adaptive
Bubble O(n) O(n²) O(n²) O(1) Yes Yes Yes
Selection O(n²) O(n²) O(n²) O(1) No Yes No
Insertion O(n) O(n²) O(n²) O(1) Yes Yes Yes
Merge O(n lg n) O(n lg n) O(n lg n) O(n) Yes No No
Algorithm Best Average Worst Space Stable In-Place Adaptive
Quick O(n lg n) O(n lg n) O(n²) O(lg n) No Yes No
Heap O(n lg n) O(n lg n) O(n lg n) O(1) No Yes No

8. CHOOSING THE RIGHT SORTING ALGORITHM


Guidelines

Use Bubble Sort:

Educational purposes
Nearly sorted small data
Not for production code

Use Insertion Sort:

Small datasets (n < 50)


Nearly sorted data
Online sorting
Practical implementation of theory

Use Merge Sort:

When O(n log n) guarantee required


Large datasets
External sorting (files)
Linked lists
When stability important

Use Quick Sort:

General-purpose sorting
Large datasets
When average O(n log n) acceptable
Cache-friendly operations
Most used in practice

Use Heap Sort:

When O(n log n) and O(1) space required


Real-time systems
Memory-constrained environments

Use Counting/Radix Sort:

When data is integers with limited range


O(n) time possible
For non-comparative sorting
EXAM PREPARATION TIPS
Important Topics to Focus
1. Big-O Analysis - Asked every exam
2. Stack Applications - Especially recursion
3. Circular Queue - Algorithm and advantages
4. Linked List Operations - Insertion, deletion
5. Binary Tree Traversals - All three types
6. Sorting Algorithms - Comparison and complexity
7. BST Properties - Definition and applications

Study Strategy
Understand concepts - Not just memorize
Trace algorithms - Work examples by hand
Implement code - Write actual C programs
Solve previous papers - Multiple times
Compare algorithms - Know trade-offs
Visual learning - Draw trees, trace sorts

Exam Pattern
Q.1 Compulsory (6 parts, 2.5 marks each)
Choose 1 from each Unit II, III, IV
Total: 75 marks exam + 25 marks classwork

Time Management (3 Hours)


Q.1: 30 minutes
Unit II: 45 minutes
Unit III: 45 minutes
Unit IV: 45 minutes
Review: 15 minutes

Study Material Created: December 29, 2025 For: [Link] 3rd Semester Data Structures Status: Complete & Ready for
Exam

You might also like