πŸ”’ Private Site

This site is password-protected.

Unit I β€” Complete Solutions to All Practice Questions


Table of Contents


Practice Questions β€” Data Structures Basics


Q1. Define the following: (a) Data (b) Data Object (c) Data Type (d) Data Structure (e) ADT.

(a) Data: Raw facts, figures, or values that have no meaning by themselves. Example: 42, "hello", 3.14.

(b) Data Object: A collection of data items (instances) that share a common set of properties. Example: All integers form a data object; all characters form a data object.

(c) Data Type: A classification that specifies:

  • The set of values a variable can hold
  • The set of operations that can be performed on those values

Example: int in C β€” values: integers in range $[-2^{31}, 2^{31}-1]$; operations: +, -, *, /, %.

(d) Data Structure: A particular way of organizing and storing data in a computer so that it can be accessed and modified efficiently. It defines the relationship between data elements and the operations allowed on them.

Example: Array (contiguous memory, indexed access), Linked List (nodes with pointers).

(e) ADT (Abstract Data Type): A mathematical model for a data type where the behavior is defined by:

  1. A set of values (domain)
  2. A set of operations on those values
  3. A set of axioms/constraints (rules the operations must follow)

The ADT specifies WHAT operations do, not HOW they are implemented. Example: Stack ADT defines push, pop, peek, isEmpty β€” without specifying whether an array or linked list is used internally.


Q2. Differentiate between a Data Type and an Abstract Data Type with an example.

Aspect Data Type Abstract Data Type (ADT)
Definition Built-in classification provided by the language Mathematical model defined by behavior
Implementation Implementation is visible and fixed Implementation is hidden (encapsulated)
Focus What values and operations the language supports What operations are available, not how they work
Example int, float, char in C Stack, Queue, List, Graph
User-defined? Usually built-in Defined by the programmer
Abstraction Level Low-level High-level

Example:

  • Data Type int: You know it uses 4 bytes, stores values $-2^{31}$ to $2^{31}-1$, supports +, -, *, /.
  • ADT Stack: You know it supports push(), pop(), peek(), isEmpty(). You do NOT know (or care) if it uses an array or linked list internally.

Q3. Give the ADT definition for a Queue. Specify data, operations, and error conditions.

ADT Queue:
    Data:
        An ordered collection of elements following FIFO (First In, First Out)
        Two markers: 'front' (removal end) and 'rear' (insertion end)

    Operations:
        create()           β†’ Initialize an empty queue
        enqueue(element)   β†’ Add element at the rear                    β€” O(1)
        dequeue()          β†’ Remove and return the front element         β€” O(1)
        front() / peek()   β†’ Return the front element without removal   β€” O(1)
        isEmpty()          β†’ Return true if queue has no elements        β€” O(1)
        isFull()           β†’ Return true if queue is at capacity         β€” O(1)
        size()             β†’ Return the number of elements               β€” O(1)

    Error Conditions:
        dequeue() on empty queue   β†’ "Queue Underflow"
        enqueue() on full queue    β†’ "Queue Overflow"
        front() on empty queue     β†’ "Queue is Empty"

    Axioms:
        1. create() produces an empty queue
        2. isEmpty(create()) = true
        3. dequeue(enqueue(q, x)) returns x if q was empty
        4. FIFO: The first element enqueued is the first dequeued

Q4. Classify data structures with a neat diagram. Give two examples of each category.

                    Data Structures
                    /             \
               Primitive       Non-Primitive
              /  |  |  \        /          \
           int float char bool  Linear    Non-Linear
                               / | | \      /    \
                         Array LL Stack Queue Tree Graph
Category Subcategory Examples
Primitive β€” int, float, char, bool
Non-Primitive β†’ Linear Static Array, String
Non-Primitive β†’ Linear Dynamic Linked List, Stack, Queue
Non-Primitive β†’ Non-Linear β€” Tree, Graph

Alternatively classified as:

Basis Type Examples
Memory Static (fixed size) Array, Stack (array-based)
Β  Dynamic (grows/shrinks) Linked List, BST
Organization Linear (sequential) Array, Stack, Queue, Linked List
Β  Non-Linear (hierarchical/network) Tree, Graph

Q5. Differentiate between static and dynamic data structures. When would you prefer one over the other?

Feature Static Data Structure Dynamic Data Structure
Size Fixed at compile time Can grow/shrink at runtime
Memory Allocated on stack or at compile time Allocated on heap using malloc/free
Access Random access β€” $O(1)$ Sequential access β€” $O(n)$ (for linked structures)
Memory Waste May waste memory (unused slots) No waste β€” allocates as needed
Examples Array, Static Stack Linked List, Dynamic Stack, BST
Insertion/Deletion Expensive β€” $O(n)$ shifting Efficient β€” $O(1)$ pointer changes

When to prefer:

  • Static: When the size is known in advance, and you need fast random access. Example: storing 100 student scores.
  • Dynamic: When the size is unpredictable or frequently changing. Example: a playlist where songs are added/removed often.

Q6. Differentiate between linear and non-linear data structures. Give three examples each.

Feature Linear Non-Linear
Arrangement Elements in a sequence (one after another) Elements in hierarchical or network structure
Levels Single level Multiple levels
Traversal Simple β€” one pass covers all elements Complex β€” multiple paths possible
Memory May or may not be contiguous Usually non-contiguous
Examples Array, Stack, Queue, Linked List Tree, Graph, Heap

Three Linear Examples:

  1. Array β€” indexed, contiguous memory
  2. Stack β€” LIFO access
  3. Queue β€” FIFO access

Three Non-Linear Examples:

  1. Binary Tree β€” hierarchical parent-child relationship
  2. Graph β€” network of interconnected nodes
  3. Heap β€” complete binary tree with heap property

Q7. Explain the relationship: Data β†’ Data Type β†’ Data Structure β†’ ADT.

This forms a hierarchy of increasing abstraction:

  1. Data β€” Raw values with no structure. Example: 5, "hello", true.

  2. Data Type β€” Gives meaning to data by defining allowed values and operations. Example: int means 5 is an integer that supports +, -, *, /.

  3. Data Structure β€” Organizes multiple data items with defined relationships and efficient access patterns. Example: An array of integers with indexed access, or a linked list with pointer-based traversal.

  4. ADT β€” The highest abstraction β€” defines WHAT operations exist without specifying HOW they are implemented. Example: Stack ADT says β€œpush adds on top, pop removes from top” β€” doesn’t specify array or linked list.

Progression: Each level adds more abstraction. Data has no structure β†’ Data Type adds meaning β†’ Data Structure adds organization β†’ ADT hides implementation details entirely.


Q8. Why is choosing the right data structure important? Give a real-world example where a poor choice leads to inefficiency.

Choosing the right data structure is critical because it determines the efficiency of all operations performed on the data.

Example β€” Contacts App (Search by Name):

Data Structure Search Time Why?
Unsorted Array $O(n)$ Must check every element linearly
Sorted Array + Binary Search $O(\log n)$ Halves the search space each time
Hash Table $O(1)$ average Direct lookup by key
BST $O(\log n)$ Tree-based search

If you store 1 million contacts in an unsorted linked list, finding a contact requires scanning up to 1 million entries. Using a hash table, the same lookup takes constant time.

Another example β€” Undo feature: Using a Queue (FIFO) would undo the oldest action first β€” completely wrong! A Stack (LIFO) correctly undoes the most recent action.


Q9. Define ADT for a β€œSet” with operations: union, intersection, difference, membership, insert, delete.

ADT Set:
    Data:
        An unordered collection of DISTINCT elements (no duplicates)

    Operations:
        create()                β†’ Initialize an empty set
        insert(element)         β†’ Add element to the set (no-op if already present)
        delete(element)         β†’ Remove element from the set
        membership(element)     β†’ Return true if element is in the set
        union(S1, S2)           β†’ Return a new set containing all elements in S1 OR S2
        intersection(S1, S2)    β†’ Return a new set containing elements in BOTH S1 AND S2
        difference(S1, S2)      β†’ Return a new set containing elements in S1 but NOT in S2
        isEmpty()               β†’ Return true if set has no elements
        size()                  β†’ Return the number of elements

    Error Conditions:
        delete(element) where element βˆ‰ Set β†’ "Element not found"

    Axioms:
        1. membership(insert(S, x), x) = true
        2. membership(create(), x) = false for all x
        3. insert(insert(S, x), x) = insert(S, x) (idempotent β€” no duplicates)
        4. union(S, βˆ…) = S
        5. intersection(S, βˆ…) = βˆ…

Q10. Match the application with the most suitable data structure.

Application Data Structure Reason
(a) Browser history Stack You go β€œback” to the most recently visited page (LIFO)
(b) File system Tree Hierarchical directory structure (folders within folders)
(c) Social network Graph Users are nodes, friendships are edges (many-to-many connections)
(d) Printer queue Queue Print jobs are served in order of arrival (FIFO)
(e) Undo feature Stack Undo reverses the most recent action (LIFO)

Practice Questions β€” Algorithms


Q1. Define an algorithm. List and explain its five essential characteristics.

Definition: An algorithm is a finite, well-defined sequence of computational steps that transforms input into output to solve a specific problem.

Five Essential Characteristics:

  1. Input β€” Zero or more well-defined inputs are provided. Example: A sorting algorithm takes an array as input.

  2. Output β€” At least one well-defined output is produced. Example: The sorted array is the output.

  3. Finiteness β€” The algorithm must terminate after a finite number of steps. A procedure that runs forever is NOT an algorithm (it’s a β€œcomputational procedure”).

  4. Definiteness β€” Each step must be precisely defined with no ambiguity. β€œSort the array somehow” is NOT definite. β€œCompare adjacent elements and swap if out of order” IS definite.

  5. Effectiveness β€” Each operation must be basic enough that it can, in principle, be carried out by a person with pencil and paper in finite time. Example: arithmetic operations, comparisons, assignments are effective. β€œFind the meaning of life” is not.


Q2. Write the pseudo code for finding the GCD of two numbers using the Euclidean algorithm.

Algorithm: EuclideanGCD(a, b)
Purpose: Find the Greatest Common Divisor of two positive integers
Input: Two positive integers a, b
Output: GCD of a and b

1. while b β‰  0 do
2.     temp ← b
3.     b ← a mod b
4.     a ← temp
5. end while
6. return a

Trace for GCD(48, 18):

Step a b a mod b
1 48 18 12
2 18 12 6
3 12 6 0
4 6 0 β€” (stop)

GCD(48, 18) = 6 βœ“

C Implementation:

int gcd(int a, int b) {
    while (b != 0) {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

Q3. Draw a flowchart to check whether a given number is prime or not.

        [Start]
           ↓
      [Read n]
           ↓
      β”Œβ”€ n ≀ 1? ──Yes──→ [Print "Not Prime"] β†’ [End]
      β”‚   No
      ↓
   [i = 2]
      ↓
   β”Œβ”€ i * i ≀ n? ──No──→ [Print "Prime"] β†’ [End]
   β”‚   Yes
   ↓
   β”Œβ”€ n % i == 0? ──Yes──→ [Print "Not Prime"] β†’ [End]
   β”‚   No
   ↓
   [i = i + 1]
      ↓
   └──→ (back to "i * i ≀ n?")

Pseudo code equivalent:

Algorithm: IsPrime(n)
1. if n ≀ 1 then return "Not Prime"
2. for i ← 2 to √n do
3.     if n mod i == 0 then return "Not Prime"
4. end for
5. return "Prime"

Q4. Write pseudo code to reverse an array of $n$ elements.

Algorithm: ReverseArray(A, n)
Purpose: Reverse array A of n elements in-place
Input: Array A[0..n-1], integer n
Output: Array A reversed

1. left ← 0
2. right ← n - 1
3. while left < right do
4.     swap(A[left], A[right])
5.     left ← left + 1
6.     right ← right - 1
7. end while

Trace for A = [1, 2, 3, 4, 5]:

Step left right Swap Array State
1 0 4 A[0]↔A[4] [5, 2, 3, 4, 1]
2 1 3 A[1]↔A[3] [5, 4, 3, 2, 1]
3 2 2 (stop, left = right) [5, 4, 3, 2, 1]

Time: $O(n)$, Space: $O(1)$


Q5. Explain the difference between a flowchart and pseudo code. When would you prefer each?

Feature Flowchart Pseudo Code
Format Graphical/visual (boxes, arrows) Textual (structured English + code-like syntax)
Ease of creation Harder for complex algorithms Easier for complex algorithms
Readability Intuitive for simple algorithms Better for detailed logic
Modification Difficult to modify Easy to modify
Documentation Good for high-level overview Good for detailed documentation
Size Can become very large and tangled Compact, scales well

When to prefer Flowchart:

  • Simple algorithms with clear branching
  • Explaining logic to non-technical stakeholders
  • Understanding control flow visually

When to prefer Pseudo Code:

  • Complex algorithms with many steps
  • Translating directly to code
  • Documenting algorithms in papers/textbooks

Q6. Write an algorithm (in pseudo code) to find the second largest element in an array.

Algorithm: SecondLargest(A, n)
Purpose: Find the second largest element in array A
Input: Array A[0..n-1], integer n (n β‰₯ 2)
Output: Second largest element

1. if n < 2 then
2.     return "Error: Need at least 2 elements"
3. end if
4. largest ← max(A[0], A[1])
5. second ← min(A[0], A[1])
6. for i ← 2 to n-1 do
7.     if A[i] > largest then
8.         second ← largest
9.         largest ← A[i]
10.    else if A[i] > second then
11.        second ← A[i]
12.    end if
13. end for
14. return second

Trace for A = [12, 35, 1, 10, 34, 1]:

i A[i] largest second
init β€” 35 12
2 1 35 12
3 10 35 12
4 34 35 34
5 1 35 34

Result: 34 βœ“

Time: $O(n)$ β€” single pass, Space: $O(1)$


Q7. Identify which of the following are valid algorithms and why.

(a) β€œKeep printing 1 forever” β€” ❌ NOT a valid algorithm

  • Violates the Finiteness property. An algorithm must terminate after a finite number of steps. This runs infinitely.

(b) β€œTake two numbers, add them, print the result” β€” βœ… Valid algorithm

  • Has input (two numbers), output (the sum), is finite (3 steps), definite (each step is clear), and effective (addition is a basic operation).

(c) β€œSort the array somehow” β€” ❌ NOT a valid algorithm

  • Violates the Definiteness property. β€œSomehow” is ambiguous β€” it doesn’t specify HOW to sort. A valid algorithm must have precisely defined steps.

Q8. Write pseudo code for the Tower of Hanoi problem with $n$ disks.

Algorithm: TowerOfHanoi(n, source, auxiliary, destination)
Purpose: Move n disks from source peg to destination peg
Input: n disks, three pegs (source, auxiliary, destination)
Output: Sequence of moves

1. if n == 1 then
2.     print "Move disk 1 from " + source + " to " + destination
3.     return
4. end if
5. TowerOfHanoi(n-1, source, destination, auxiliary)
6. print "Move disk " + n + " from " + source + " to " + destination
7. TowerOfHanoi(n-1, auxiliary, source, destination)

Trace for n = 3 (A→C, using B as auxiliary):

Step Move
1 Move disk 1 from A to C
2 Move disk 2 from A to B
3 Move disk 1 from C to B
4 Move disk 3 from A to C
5 Move disk 1 from B to A
6 Move disk 2 from B to C
7 Move disk 1 from A to C

Total moves = $2^n - 1 = 2^3 - 1 = 7$

Time Complexity: $T(n) = 2T(n-1) + 1 = O(2^n)$


Q9. Draw a flowchart for binary search on a sorted array.

        [Start]
           ↓
    [Read A[], n, key]
           ↓
    [low = 0, high = n-1]
           ↓
    β”Œβ”€β”€ low ≀ high? ──No──→ [Print "Not Found"] β†’ [End]
    β”‚     Yes
    ↓
    [mid = (low + high) / 2]
           ↓
    β”Œβ”€β”€ A[mid] == key? ──Yes──→ [Print "Found at mid"] β†’ [End]
    β”‚     No
    ↓
    β”Œβ”€β”€ A[mid] < key? ──Yes──→ [low = mid + 1] ──┐
    β”‚     No                                       β”‚
    ↓                                              β”‚
    [high = mid - 1] β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           ↓
    └──→ (back to "low ≀ high?")

Key idea: Repeatedly halve the search space by comparing the middle element with the key.


Q10. Write an algorithm using proper header, purpose, conditions, and loop notations to find all even numbers in an array.

Algorithm: FindEvenNumbers
Purpose: Find and display all even numbers in an array
Input: Array A[0..n-1] of integers, integer n
Output: All even numbers in the array
Pre-condition: n β‰₯ 1

Steps:
1. [Initialize] count ← 0
2. [Traverse array]
   Repeat for i ← 0 to n-1:
       2.1 [Check even]
           if A[i] mod 2 == 0 then
               print A[i]
               count ← count + 1
           end if
   [End of loop]
3. [Output count]
   print "Total even numbers: " + count
4. [Finished]
   return

C Implementation:

void findEven(int A[], int n) {
    int count = 0;
    for (int i = 0; i < n; i++) {
        if (A[i] % 2 == 0) {
            printf("%d ", A[i]);
            count++;
        }
    }
    printf("\nTotal even numbers: %d\n", count);
}

Time: $O(n)$, Space: $O(1)$


Practice Questions β€” Algorithm Analysis


Q1. Define time complexity and space complexity. Why is time complexity more commonly discussed?

Time Complexity: A function that describes the amount of time (number of basic operations) an algorithm takes as a function of the input size $n$.

Space Complexity: A function that describes the amount of extra memory (beyond the input itself) an algorithm uses as a function of $n$.

Why time is more commonly discussed:

  1. Memory is reusable β€” space can be freed and reused, but time once spent is gone forever.
  2. Time is the main bottleneck β€” most algorithms run out of time before running out of memory.
  3. Memory is cheap β€” modern systems have abundant RAM, but users won’t wait for slow algorithms.
  4. Time is more variable β€” space usage is often straightforward ($O(1)$ or $O(n)$), while time complexity varies widely ($O(\log n)$ to $O(n!)$).

Q2. Explain Big O, Omega, and Theta notations with formal definitions and examples.

Big O β€” $O(g(n))$ β€” Upper Bound (Worst Case)

$f(n) = O(g(n))$ if there exist constants $c > 0$ and $n_0 > 0$ such that:

\[f(n) \leq c \cdot g(n) \quad \text{for all } n \geq n_0\]

β€œ$f(n)$ grows at most as fast as $g(n)$.”

Example: $3n + 5 = O(n)$ β€” choose $c = 4, n_0 = 5$: $3n + 5 \leq 4n$ for $n \geq 5$. βœ“

Big Omega β€” $\Omega(g(n))$ β€” Lower Bound (Best Case)

$f(n) = \Omega(g(n))$ if there exist constants $c > 0$ and $n_0 > 0$ such that:

\[f(n) \geq c \cdot g(n) \quad \text{for all } n \geq n_0\]

β€œ$f(n)$ grows at least as fast as $g(n)$.”

Example: $3n + 5 = \Omega(n)$ β€” choose $c = 1, n_0 = 1$: $3n + 5 \geq n$ for $n \geq 1$. βœ“

Big Theta β€” $\Theta(g(n))$ β€” Tight Bound (Exact Growth Rate)

$f(n) = \Theta(g(n))$ if there exist constants $c_1, c_2 > 0$ and $n_0 > 0$ such that:

\[c_1 \cdot g(n) \leq f(n) \leq c_2 \cdot g(n) \quad \text{for all } n \geq n_0\]

β€œ$f(n)$ grows exactly as fast as $g(n)$.”

Example: $3n + 5 = \Theta(n)$ β€” choose $c_1 = 1, c_2 = 4, n_0 = 5$. βœ“


Q3. Prove that $5n^2 + 3n + 100 = O(n^2)$.

To prove: Find constants $c > 0$ and $n_0 > 0$ such that $5n^2 + 3n + 100 \leq c \cdot n^2$ for all $n \geq n_0$.

Proof:

For $n \geq 1$:

  • $3n \leq 3n^2$ (since $n \leq n^2$ for $n \geq 1$)
  • $100 \leq 100n^2$ (since $1 \leq n^2$ for $n \geq 1$)

Therefore: $5n^2 + 3n + 100 \leq 5n^2 + 3n^2 + 100n^2 = 108n^2$

So with $c = 108$ and $n_0 = 1$:

\[5n^2 + 3n + 100 \leq 108 \cdot n^2 \quad \text{for all } n \geq 1\]

Tighter bound: For $n \geq 10$: $3n \leq 0.03n^2$ and $100 \leq n^2$. So $c = 6.03, n_0 = 10$ also works.

Therefore $5n^2 + 3n + 100 = O(n^2)$. $\blacksquare$


Q4. Prove that $n^2 \neq O(n)$.

Proof by contradiction:

Assume $n^2 = O(n)$. Then there exist constants $c > 0$ and $n_0 > 0$ such that:

\[n^2 \leq c \cdot n \quad \text{for all } n \geq n_0\]

Dividing both sides by $n$ (valid since $n > 0$):

\[n \leq c \quad \text{for all } n \geq n_0\]

But this is a contradiction β€” $n$ grows without bound, so for any fixed constant $c$, we can always find $n > c$ (simply choose $n = \lceil c \rceil + 1$).

Therefore, no such $c$ and $n_0$ exist, and $n^2 \neq O(n)$. $\blacksquare$


Q5. Arrange in increasing order of growth rate.

\[O(1) < O(\log n) < O(n) < O(n \log n) < O(n^2) < O(n^3) < O(2^n) < O(n!)\]

Growth comparison at $n = 100$:

Function Value
$O(1)$ $1$
$O(\log n)$ $\approx 7$
$O(n)$ $100$
$O(n \log n)$ $\approx 664$
$O(n^2)$ $10{,}000$
$O(n^3)$ $1{,}000{,}000$
$O(2^n)$ $\approx 1.27 \times 10^{30}$
$O(n!)$ $\approx 9.33 \times 10^{157}$

Q6. Find the time complexity of the nested loop with j += i.

for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j += i) {
        printf("*");
    }
}

The inner loop runs $\lceil n/i \rceil$ times for each value of i.

Total operations = $\sum_{i=1}^{n} \frac{n}{i} = n \cdot \sum_{i=1}^{n} \frac{1}{i} = n \cdot H_n$

where $H_n = 1 + \frac{1}{2} + \frac{1}{3} + … + \frac{1}{n}$ is the Harmonic series.

Since $H_n = \Theta(\ln n)$:

\[\text{Total} = n \cdot \Theta(\ln n) = \Theta(n \log n)\]

Answer: $O(n \log n)$


Q7. Find the time complexity of the triple nested loop.

for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
        for (int k = 0; k < n; k++)
            // O(1) work

Each loop independently runs $n$ times. By the multiplication rule:

\[n \times n \times n = n^3\]

Answer: $O(n^3)$


Q8. Time and space complexity of recursive Fibonacci.

int fib(int n) {
    if (n <= 1) return n;
    return fib(n-1) + fib(n-2);
}

Time Complexity: $O(2^n)$

The recurrence is $T(n) = T(n-1) + T(n-2) + O(1)$.

The recursion tree is a binary tree where each call spawns two more. At depth $k$, there are up to $2^k$ calls. The tree has depth $n$, giving roughly $2^n$ total calls.

More precisely, $T(n) = O(\phi^n)$ where $\phi = \frac{1+\sqrt{5}}{2} \approx 1.618$ (golden ratio), but $O(2^n)$ is the standard upper bound.

Space Complexity: $O(n)$

At any point, only ONE branch of the recursion tree is active on the call stack. The maximum depth is $n$ (following the leftmost path: $fib(n) \to fib(n-1) \to … \to fib(1)$). So the stack holds at most $n$ frames.


Q9. Differentiate between Best, Average, and Worst case analysis.

Case Definition Usefulness
Best Case Minimum time taken (most favorable input) Rarely useful β€” too optimistic
Average Case Expected time over all possible inputs Most realistic but hard to calculate
Worst Case Maximum time taken (least favorable input) Most commonly used β€” guarantees upper bound

Linear Search Example (searching for key in array of $n$ elements):

Case When? Comparisons
Best Key is the first element $1 = O(1)$
Average Key is equally likely in any position $\frac{n}{2} = O(n)$
Worst Key is the last element or not present $n = O(n)$

Bubble Sort Example:

Case When? Comparisons
Best Array is already sorted (with optimized version) $n-1 = O(n)$
Average Random order $O(n^2)$
Worst Array is in reverse order $\frac{n(n-1)}{2} = O(n^2)$

Q10. Explain why we drop constants in Big O notation. Is $O(100n)$ the same as $O(n)$?

Yes, $O(100n) = O(n)$.

Why constants are dropped:

  1. Big O describes growth rate, not actual time. We care about how the function behaves as $n \to \infty$, not specific values.

  2. Constants depend on hardware. An algorithm taking $100n$ operations on a slow machine may be faster than $n$ operations on an even slower machine. Constants are machine-dependent.

  3. Mathematical definition allows it. If $f(n) = 100n$, then $f(n) \leq 100 \cdot n$ for all $n \geq 1$. With $c = 100$, this satisfies the Big O definition for $O(n)$.

  4. Asymptotic dominance matters. For large $n$: $100n$ vs $n^2$ β€” eventually $n^2$ overtakes $100n$ (at $n = 100$). The growth rate of $n^2$ is fundamentally different from $n$, regardless of constants.

Key insight: $O(100n) = O(n)$ but $O(n) \neq O(n^2)$. Constants don’t change the complexity class.


Q11. Find the time complexity of the i = i / 3 loop.

int i = n;
while (i > 0) {
    i = i / 3;
}

After $k$ iterations: $i = \frac{n}{3^k}$

The loop stops when $i = 0$ (integer division), which happens when $3^k > n$:

\[k = \lceil \log_3 n \rceil\]

Since $\log_3 n = \frac{\log_2 n}{\log_2 3}$, and base changes are just constant factors:

Answer: $O(\log n)$

Note: Dividing by ANY constant $> 1$ gives logarithmic complexity.


Q12. Express $T(n) = 3n^2 + 7n \log n + 100$ in all three notations.

The dominant term is $3n^2$ (since $n^2$ grows faster than $n \log n$).

Big O (upper bound): $T(n) = O(n^2)$

For $n \geq 1$: $3n^2 + 7n\log n + 100 \leq 3n^2 + 7n^2 + 100n^2 = 110n^2$. So $c = 110$, $n_0 = 1$.

Big Omega (lower bound): $T(n) = \Omega(n^2)$

$3n^2 + 7n\log n + 100 \geq 3n^2$ for all $n \geq 1$. So $c = 3$, $n_0 = 1$.

Big Theta (tight bound): $T(n) = \Theta(n^2)$

Since $T(n) = O(n^2)$ AND $T(n) = \Omega(n^2)$, we have $T(n) = \Theta(n^2)$.

\[3n^2 \leq 3n^2 + 7n\log n + 100 \leq 110n^2 \quad \text{for } n \geq 1\]

Comprehensive Unit I Practice Set


1. What is the difference between data and information?

Aspect Data Information
Definition Raw, unprocessed facts and figures Processed, organized, meaningful data
Meaning No inherent meaning Has context and meaning
Example 25, "Delhi", 38.5 β€œTemperature in Delhi is 38.5Β°C”
Usefulness Not directly useful for decisions Useful for decision-making
Processing Input to processing Output of processing

Data β†’ Processing β†’ Information


2. Define: (a) Data Type (b) Abstract Data Type (c) Data Structure

(a) Data Type: A classification that specifies the domain of values and the set of operations for a variable. Examples: int, float, char.

(b) Abstract Data Type (ADT): A mathematical model defining a data type purely by its behavior (operations and constraints), independent of implementation. It specifies WHAT, not HOW. Examples: Stack, Queue, List.

(c) Data Structure: A concrete way of organizing, storing, and managing data in memory to enable efficient access and modification. It implements an ADT. Examples: Array, Linked List, Hash Table.


3. Give two real-world examples each of linear and non-linear data structures.

Linear:

  1. Queue at a movie theater β€” people wait in a line (FIFO order)
  2. Stack of plates β€” you take from the top (LIFO order)

Non-Linear:

  1. Company organizational chart β€” hierarchical (tree structure)
  2. Road network between cities β€” interconnected (graph structure)

4. Write the ADT for a β€œBag” (unordered collection that allows duplicates).

ADT Bag:
    Data:
        An unordered collection of elements that ALLOWS DUPLICATES

    Operations:
        create()           β†’ Initialize an empty bag
        add(element)       β†’ Add an element to the bag
        remove(element)    β†’ Remove one occurrence of element (if exists)
        contains(element)  β†’ Return true if element is in the bag
        count(element)     β†’ Return number of occurrences of element
        size()             β†’ Return total number of elements
        isEmpty()          β†’ Return true if bag has no elements
        clear()            β†’ Remove all elements

    Error Conditions:
        remove(element) where element βˆ‰ Bag β†’ "Element not found"

    Axioms:
        1. isEmpty(create()) = true
        2. size(add(B, x)) = size(B) + 1
        3. contains(add(B, x), x) = true
        4. count(add(B, x), x) = count(B, x) + 1

Key difference from Set: A Bag allows duplicates. add(B, 5) twice means count(B, 5) = 2.


5. What are the five characteristics of an algorithm?

  1. Input β€” Zero or more well-defined inputs
  2. Output β€” At least one well-defined output
  3. Finiteness β€” Must terminate after a finite number of steps
  4. Definiteness β€” Each step must be precisely and unambiguously defined
  5. Effectiveness β€” Each step must be basic enough to be carried out mechanically

6. Differentiate between flowchart and pseudo code.

Feature Flowchart Pseudo Code
Representation Graphical (shapes + arrows) Textual (structured English)
Complexity handling Gets messy for complex algorithms Handles complexity well
Ease of modification Hard to modify Easy to modify
Conversion to code Requires interpretation Almost direct translation
Standardization ISO standard symbols exist No universal standard

7. Determine the time complexity of each code fragment.

(a) Inner loop runs $i^2$ times: \(\text{Total} = \sum_{i=1}^{n} i^2 = \frac{n(n+1)(2n+1)}{6} = O(n^3)\)

(b) Outer loop halves $i$: $\log n$ iterations. Inner loop always runs $n$ times: \(\text{Total} = n \cdot \log n = O(n \log n)\)

(c) Trick question! Variable j is NOT reset inside the outer loop.

  • First outer iteration: inner loop runs $n$ times ($j$ goes 0 to $n$)
  • All subsequent iterations: $j$ is already $n$, inner loop runs 0 times.
  • Total: $O(n)$, NOT $O(n^2)$!

8. Prove that $O(n^2) + O(n) = O(n^2)$.

Let $f(n) = O(n^2)$ and $g(n) = O(n)$. Then:

  • $f(n) \leq c_1 \cdot n^2$ for $n \geq n_1$
  • $g(n) \leq c_2 \cdot n$ for $n \geq n_2$

For $n \geq \max(n_1, n_2)$:

\[f(n) + g(n) \leq c_1 \cdot n^2 + c_2 \cdot n \leq c_1 \cdot n^2 + c_2 \cdot n^2 = (c_1 + c_2) \cdot n^2\]

With $c = c_1 + c_2$ and $n_0 = \max(n_1, n_2, 1)$:

\[f(n) + g(n) \leq c \cdot n^2 \quad \text{for all } n \geq n_0\]

Therefore $f(n) + g(n) = O(n^2)$. $\blacksquare$

General rule: $O(n^a) + O(n^b) = O(n^{\max(a,b)})$ β€” the higher-order term dominates.


9. If Algorithm A takes $100n$ operations and Algorithm B takes $n^2$ operations, for what values of $n$ is A better?

A is better when $100n < n^2$:

\[100n < n^2 \implies 100 < n \implies n > 100\]
$n$ Algorithm A ($100n$) Algorithm B ($n^2$) Winner
10 1,000 100 B
50 5,000 2,500 B
100 10,000 10,000 Tie
200 20,000 40,000 A
1000 100,000 1,000,000 A

A is better for $n > 100$. B is better for $n < 100$. They tie at $n = 100$.

This illustrates why Big O drops constants β€” for large inputs, $O(n)$ always beats $O(n^2)$ regardless of the constant factor.


10. Write algorithms for: (a) Sum of digits, (b) Palindrome check, (c) Sieve of Eratosthenes.

(a) Sum of Digits:

Algorithm: SumOfDigits(n)
Input: Positive integer n
Output: Sum of all digits of n

1. sum ← 0
2. while n > 0 do
3.     sum ← sum + (n mod 10)
4.     n ← n / 10  (integer division)
5. end while
6. return sum

Example: $n = 1234$: $4 + 3 + 2 + 1 = 10$. Time: $O(\log_{10} n)$

(b) Palindrome Check:

Algorithm: IsPalindrome(S, n)
Input: String S of length n
Output: true if S is a palindrome, false otherwise

1. left ← 0
2. right ← n - 1
3. while left < right do
4.     if S[left] β‰  S[right] then return false
5.     left ← left + 1
6.     right ← right - 1
7. end while
8. return true

Example: β€œmadam” β†’ m=m, a=a, d=d β†’ true. Time: $O(n)$

(c) Sieve of Eratosthenes:

Algorithm: SieveOfEratosthenes(n)
Input: Integer n β‰₯ 2
Output: All prime numbers from 2 to n

1. Create boolean array isPrime[0..n], initialize all to true
2. isPrime[0] ← false, isPrime[1] ← false
3. for i ← 2 to √n do
4.     if isPrime[i] = true then
5.         for j ← i*i to n step i do
6.             isPrime[j] ← false
7.         end for
8.     end if
9. end for
10. for i ← 2 to n do
11.     if isPrime[i] then print i
12. end for

Time: $O(n \log \log n)$, Space: $O(n)$


11. Explain the classification of data structures with a detailed tree diagram.

                         Data Structures
                        /               \
                 Primitive           Non-Primitive
                /  |  |  \           /          \
             int float char bool  Linear      Non-Linear
                                 /  |  \       /       \
                              Array LL  Stack  Tree    Graph
                                    |   Queue   |
                              Singly/Doubly/   BST
                              Circular     AVL/Heap
Type Structure Application
Array Contiguous, indexed Image pixels, matrices, lookup tables
Linked List Nodes with pointers Music playlists, memory management
Stack LIFO Undo operations, expression evaluation, recursion
Queue FIFO Print queues, BFS, CPU scheduling
Tree Hierarchical File systems, HTML DOM, databases (B-trees)
Graph Network Social networks, GPS navigation, web crawling
Hash Table Key-value mapping Dictionaries, caches, symbol tables

12. Compare Big O, Big Omega, and Big Theta notations.

Notation Symbol Bound Type Meaning Analogy
Big O $O$ Upper bound $f(n) \leq c \cdot g(n)$ ≀ (at most)
Big Omega $\Omega$ Lower bound $f(n) \geq c \cdot g(n)$ β‰₯ (at least)
Big Theta $\Theta$ Tight bound $c_1 g(n) \leq f(n) \leq c_2 g(n)$ = (exactly)

Example with $f(n) = 3n^2 + 5n$:

  • $f(n) = O(n^2)$ βœ“ and also $O(n^3)$ βœ“ (upper bound can be loose)
  • $f(n) = \Omega(n^2)$ βœ“ and also $\Omega(n)$ βœ“ (lower bound can be loose)
  • $f(n) = \Theta(n^2)$ βœ“ β€” this is the tightest and most informative

Relationship: $f(n) = \Theta(g(n))$ if and only if $f(n) = O(g(n))$ AND $f(n) = \Omega(g(n))$.


13. Best, Average, and Worst case analysis with Insertion Sort.

Insertion Sort Algorithm: For each element, insert it into its correct position in the already-sorted portion.

Best Case β€” Already Sorted Array $[1, 2, 3, 4, 5]$:

  • Each element is already in the right position
  • Inner loop comparison: $A[j] > key$ is false immediately
  • Comparisons per element: 1
  • Total: $(n-1) \times 1 = n - 1$
  • Time: $O(n)$

Worst Case β€” Reverse Sorted Array $[5, 4, 3, 2, 1]$:

  • Each element must be moved to the very beginning
  • Element at position $i$ requires $i$ comparisons and shifts
  • Total comparisons: $1 + 2 + 3 + … + (n-1) = \frac{n(n-1)}{2}$
  • Time: $O(n^2)$

Average Case β€” Random Array:

  • On average, each element is compared with half the sorted portion
  • Total: $\frac{1}{2}(1 + 2 + … + (n-1)) = \frac{n(n-1)}{4}$
  • Time: $O(n^2)$
Case Input Comparisons Time
Best Sorted $n - 1$ $O(n)$
Average Random $\frac{n(n-1)}{4}$ $O(n^2)$
Worst Reverse sorted $\frac{n(n-1)}{2}$ $O(n^2)$

πŸ“ Back to Unit I Notes β†’

← Back to DSA Index