C Algorithms: Recursion, Divide-and-Conquer & Greedy Paradigm Masterclass
Welcome to Phase 19 (Chapter 53): C Algorithms โ Recursion, Divide-and-Conquer & Greedy Paradigm Masterclass! Design paradigms provide templates for solving complex problems. In this guide, you will master recursion mechanics, Divide-and-Conquer strategies, and Greedy Choice algorithms in C.
Recursion occurs when a function calls itself to solve smaller subproblems. Tail Recursion happens when the recursive call is the final statement in the function, allowing compilers (GCC `-O2`) to optimize stack frames away into a simple loop!
Divide-and-Conquer breaks a problem into smaller independent subproblems, solves them recursively, and combines results (e.g. Merge Sort, Binary Search).
#include <stdio.h>
#include <stdlib.h>
typedef struct {
double weight;
double value;
double ratio; // value / weight
} Item;
static int compareItems(const void *a, const void *b) {
Item *i1 = (Item *)a;
Item *i2 = (Item *)b;
if (i2->ratio > i1->ratio) return 1;
if (i2->ratio < i1->ratio) return -1;
return 0;
}
double fractionalKnapsack(Item items[], int n, double capacity) {
qsort(items, n, sizeof(Item), compareItems);
double totalValue = 0.0;
for (int i = 0; i < n; i++) {
if (capacity <= 0) break;
if (items[i].weight <= capacity) {
capacity -= items[i].weight;
totalValue += items[i].value;
} else {
totalValue += items[i].value * (capacity / items[i].weight);
capacity = 0;
}
}
return totalValue;
}
int main(void) {
Item items[] = {{10, 60, 6.0}, {20, 100, 5.0}, {30, 120, 4.0}};
double maxVal = fractionalKnapsack(items, 3, 50.0);
printf("Maximum Knapsack Value: %.2f\n", maxVal);
return 0;
} Q1: What is the core difference between Greedy and Dynamic Programming?
Greedy makes a locally optimal choice at each step without reconsidering past decisions. DP evaluates all subproblem choices and stores optimal solutions to subproblems.
Q2: Does Greedy strategy always guarantee the global optimal solution?
No! Greedy fails for 0/1 Knapsack, but works for Fractional Knapsack, Huffman Coding, and Prim's/Dijkstra's algorithms.
Q3: What causes stack overflow in recursion?
Missing base cases or excessively deep recursive calls exhaust the allocated RAM stack memory frame limit.
Q4: How does tail call optimization work in GCC?
GCC reuses the current stack frame for the next recursive function call instead of allocating a new frame.
Q5: What is the Master Theorem in Divide-and-Conquer?
A mathematical formula used to solve recurrence relations of the form T(N) = aT(N/b) + f(N).