462: Algorithm Analysis¶
Complexity analysis and design of advanced algorithmic strategies.
Topics¶
Asymptotic notation: O, Ω, Θ
Divide-and-conquer algorithms
Dynamic programming
Greedy algorithms
Graph algorithms (shortest path, MST, topological sort)
NP-completeness and reduction proofs
Projects¶
Travelling Salesman Problem (462/tsp/tsp.c)¶
Solves the Travelling Salesman Problem using branch-and-bound search. Reads city coordinates from stdin, computes pairwise distances, and finds the shortest tour with a bounding function to prune the search tree.
typedef struct s_node {
int level;
int *path;
float bound;
} *t_node;
float best_length = FLT_MAX;
int *best_path;
t_node give_birth(t_node parent);
t_node give_path(t_node parent, t_node kid);
float get_bound(t_node n);
/* branch-and-bound: prune subtrees whose lower bound exceeds best known tour */
void search(t_node node) {
if (node->bound >= best_length) return;
if (node->level == d) {
if (node->bound < best_length) {
best_length = node->bound;
memcpy(best_path, node->path, d * sizeof(int));
}
return;
}
for (int i = 0; i < d; i++) {
t_node child = give_birth(node);
give_path(node, child);
search(child);
}
}
Floyd-Warshall All-Pairs Shortest Path (462/floyd/)¶
Two implementations (floyd1.c, floyd2.c) of the Floyd-Warshall algorithm on a
5-node weighted graph, computing shortest paths between every pair of vertices in O(V³) time.
/* D[i][j] = shortest path i→j; P[i][j] = intermediate vertex */
for (k = 1; k <= N; k++)
for (i = 1; i <= N; i++)
for (j = 1; j <= N; j++)
if (D[i][k] + D[k][j] < D[i][j]) {
D[i][j] = D[i][k] + D[k][j];
P[i][j] = k;
}
Quicksort (462/sorting/quicksort.c, 462/sorting/sort_main.c)¶
A partition-based quicksort implementation alongside a driver (sort_main.c) that reads
integer arrays from stdin, sorts them, and outputs the result.
void quicksort(int lo, int hi) {
if (lo < hi) {
int pivot = partition(lo, hi);
quicksort(lo, pivot - 1);
quicksort(pivot + 1, hi);
}
}
Priority Queue / Binary Heap (462/sorting/pq.cpp)¶
A C++ binary min-heap implementation with insert and extract-min operations,
demonstrating the heap data structure underlying efficient priority queues and heap sort.
PQ_Entry Priority_Q::Extract_Min() {
assert(Entry_Ct > 0);
PQ_Entry result = Data[1]; /* root is the minimum */
Data[1] = Data[Entry_Ct--]; /* move last element to root */
Sift_Down(1); /* restore heap property */
return result;
}
Pascal’s Triangle (462/pasc/pascals_triangle.c)¶
Generates Pascal’s triangle using dynamic programming, illustrating how combinatorial identities (binomial coefficients) can be computed iteratively in O(n²) time and space.
/* Each row reuses array b[], updating right-to-left */
for (i = 0; i <= n; i++) {
for (j = i; j >= 0; j--) {
b[j] = (j == 0 || j == i) ? 1 : b[j] + b[j - 1];
printf("%d ", b[j]);
}
printf("\n");
}