<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Algorithms | Portfolio</title><link>https://ansangah.github.io/en/tags/algorithms/</link><atom:link href="https://ansangah.github.io/en/tags/algorithms/index.xml" rel="self" type="application/rss+xml"/><description>Algorithms</description><generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>en</language><lastBuildDate>Thu, 10 Oct 2024 00:00:00 +0000</lastBuildDate><image><url>https://ansangah.github.io/media/sharing.png</url><title>Algorithms</title><link>https://ansangah.github.io/en/tags/algorithms/</link></image><item><title>Algorithms</title><link>https://ansangah.github.io/en/blog/subjects/algorithm/</link><pubDate>Thu, 10 Oct 2024 00:00:00 +0000</pubDate><guid>https://ansangah.github.io/en/blog/subjects/algorithm/</guid><description>&lt;h2 id="1-overview"&gt;1. Overview&lt;/h2&gt;
&lt;p&gt;This note compiles the key concepts covered in an undergraduate algorithms course. Use it to refresh important ideas quickly and to understand how the individual topics are connected.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="2-sorting-algorithms"&gt;2. Sorting Algorithms&lt;/h2&gt;
&lt;p&gt;Sorting is the preparatory step for many problems. When choosing an algorithm, consider input size, data distribution, auxiliary space, and whether stability (preserving the order of equal keys) matters.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Algorithm&lt;/th&gt;
&lt;th&gt;Average Time&lt;/th&gt;
&lt;th&gt;Worst Time&lt;/th&gt;
&lt;th&gt;Extra Space&lt;/th&gt;
&lt;th&gt;Highlights&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Merge Sort&lt;/td&gt;
&lt;td&gt;O(n log n)&lt;/td&gt;
&lt;td&gt;O(n log n)&lt;/td&gt;
&lt;td&gt;O(n)&lt;/td&gt;
&lt;td&gt;Stable; great for external sorting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quick Sort&lt;/td&gt;
&lt;td&gt;O(n log n)&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;td&gt;O(log n)&lt;/td&gt;
&lt;td&gt;Divide and conquer; pivot choice is critical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Selection Sort&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;td&gt;O(1)&lt;/td&gt;
&lt;td&gt;Few swaps but generally slow; unstable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bubble Sort&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;td&gt;O(1)&lt;/td&gt;
&lt;td&gt;Simple; fast on nearly sorted data with early exit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insertion Sort&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;td&gt;O(1)&lt;/td&gt;
&lt;td&gt;Excellent for small or nearly sorted arrays; stable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Radix Sort&lt;/td&gt;
&lt;td&gt;O(d·n)&lt;/td&gt;
&lt;td&gt;O(d·n)&lt;/td&gt;
&lt;td&gt;O(n + k)&lt;/td&gt;
&lt;td&gt;Digit-wise; bypasses comparisons&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Counting/Bucket Sort&lt;/td&gt;
&lt;td&gt;O(n + k)&lt;/td&gt;
&lt;td&gt;O(n + k)&lt;/td&gt;
&lt;td&gt;O(n + k)&lt;/td&gt;
&lt;td&gt;Strong when value range is small or uniform&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="21-merge-sort"&gt;2.1 Merge Sort&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Recursively splits the array and merges the sorted halves.&lt;/li&gt;
&lt;li&gt;Stable because equal keys retain their relative order.&lt;/li&gt;
&lt;li&gt;Drawbacks: needs extra memory and incurs recursion overhead.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="22-quick-sort"&gt;2.2 Quick Sort&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Partitions around a pivot into smaller and larger elements and recurses.&lt;/li&gt;
&lt;li&gt;Typically the fastest in practice, but degenerates to O(n²) on sorted data unless you randomise or choose smart pivots (median-of-three, etc.).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="23-selection-sort"&gt;2.3 Selection Sort&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Repeatedly selects the minimum (or maximum) remaining element and swaps it into place.&lt;/li&gt;
&lt;li&gt;Swap count is limited to O(n), but the algorithm is mainly pedagogical due to its O(n²) comparisons.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="24-bubble-sort"&gt;2.4 Bubble Sort&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Repeatedly swaps adjacent elements that are out of order so the largest “bubbles” to the end.&lt;/li&gt;
&lt;li&gt;Each pass places one element; adding a flag for “already sorted” speeds up nearly sorted inputs.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="25-insertion-sort"&gt;2.5 Insertion Sort&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Inserts each element into the correct position within the already sorted prefix.&lt;/li&gt;
&lt;li&gt;Stable and efficient for tiny datasets or partially ordered inputs.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="26-radix-sort"&gt;2.6 Radix Sort&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Sorts integers or fixed-length strings digit by digit: LSD (least significant digit first) or MSD (most significant digit first).&lt;/li&gt;
&lt;li&gt;Requires a stable subroutine (e.g., counting sort) to guarantee global stability.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="27-counting--bucket-sort"&gt;2.7 Counting &amp;amp; Bucket Sort&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Counting sort achieves O(n + k) for small value range k; bucket sort achieves expected O(n) when inputs are uniformly distributed.&lt;/li&gt;
&lt;li&gt;Both need extra memory and require advance knowledge of the key range.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="3-trees-red-black-trees"&gt;3. Trees: Red-Black Trees&lt;/h2&gt;
&lt;p&gt;Red-black trees are balanced binary search trees that maintain O(log n) height by enforcing colour-based invariants.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Invariants:&lt;/strong&gt;&lt;br&gt;
(1) Every node is red or black.&lt;br&gt;
(2) The root and NIL leaves are black.&lt;br&gt;
(3) Red nodes have black children.&lt;br&gt;
(4) Every path from a node to its descendant NIL nodes contains the same number of black nodes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Operations:&lt;/strong&gt;&lt;br&gt;
Insert like a BST, then fix colours/rotations. Delete by replacing with a successor and resolving the “double black” case.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Why use them:&lt;/strong&gt; Fewer rotations than AVL trees, making them practical when inserts/deletes are frequent.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Examples:&lt;/strong&gt; &lt;code&gt;std::map&lt;/code&gt;, &lt;code&gt;std::set&lt;/code&gt;, Java &lt;code&gt;TreeMap&lt;/code&gt;, Linux CFS scheduler.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="4-hash-tables"&gt;4. Hash Tables&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Idea:&lt;/strong&gt; Hash a key to an array index so average lookup/insertion/deletion becomes O(1).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Collision:&lt;/strong&gt; When multiple keys hash to the same bucket. Quality of the hash function and load factor (n/m) dictate performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="41-collision-resolution-strategies"&gt;4.1 Collision-Resolution Strategies&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Separate chaining:&lt;/strong&gt; Linked lists or dynamic arrays per bucket. Simple and flexible, but needs pointer storage.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Open addressing:&lt;/strong&gt; Probe for the next empty slot (linear, quadratic probing, double hashing). Cache-friendly, yet suffers from clustering.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rehashing:&lt;/strong&gt; Enlarge the table when the load factor exceeds a threshold and reinsert all entries.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="42-design-tips"&gt;4.2 Design Tips&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Aim for a hash function that distributes keys evenly, is fast to compute, and resists adversarial input.&lt;/li&gt;
&lt;li&gt;For concurrent scenarios, look into lock-free buckets, striped locks, or partitioned tables.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="5-graph-algorithms"&gt;5. Graph Algorithms&lt;/h2&gt;
&lt;p&gt;Graphs model networks, dependency orders, and relationships. Sparse graphs typically use adjacency lists; dense graphs favour adjacency matrices.&lt;/p&gt;
&lt;h3 id="51-topological-sort"&gt;5.1 Topological Sort&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Produces a linear order of a DAG’s prerequisites.&lt;/li&gt;
&lt;li&gt;Implement via Kahn’s algorithm (in-degree queue) or DFS finishing times; both detect cycles when sorting fails.&lt;/li&gt;
&lt;li&gt;Useful for course prerequisites, build systems, and task scheduling.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="52-bellmanford-algorithm"&gt;5.2 Bellman–Ford Algorithm&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Handles graphs with negative edge weights to find single-source shortest paths.&lt;/li&gt;
&lt;li&gt;Runs |V|−1 relaxations and checks for updates on the |V|th iteration to detect negative cycles.&lt;/li&gt;
&lt;li&gt;Critical for routing protocols such as RIP where Dijkstra cannot be applied.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="53-pebble-game"&gt;5.3 Pebble Game&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Places “pebbles” on DAG nodes to study computation order and resource usage.&lt;/li&gt;
&lt;li&gt;Helps derive lower bounds for register allocation, memory minimisation, and proof complexity.&lt;/li&gt;
&lt;li&gt;Solving the optimal pebbling strategy is challenging beyond restricted graph classes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="54-additional-highlights"&gt;5.4 Additional Highlights&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DFS/BFS:&lt;/strong&gt; Core search routines; basis for connectivity, cycle detection, and topological sort.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Strongly Connected Components:&lt;/strong&gt; Kosaraju’s or Tarjan’s algorithms condense graphs into DAGs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Minimum Spanning Tree:&lt;/strong&gt; Kruskal and Prim minimise connection cost in undirected weighted graphs.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="6-string-matching-rabinkarp"&gt;6. String Matching: Rabin–Karp&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Uses a rolling hash to compare the pattern hash with substrings of the text.&lt;/li&gt;
&lt;li&gt;Offers expected O(n + m) time; collisions trigger explicit substring comparisons.&lt;/li&gt;
&lt;li&gt;Particularly handy for multi-pattern search after precomputing pattern hashes.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="7-study-tips"&gt;7. Study Tips&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Implement algorithms and analyse both average and worst cases using your own test datasets.&lt;/li&gt;
&lt;li&gt;Visualise algorithm steps with tools such as VisuAlgo or CS Academy.&lt;/li&gt;
&lt;li&gt;In coding interviews or contests, inspect input bounds and memory constraints before choosing a strategy.&lt;/li&gt;
&lt;li&gt;Suggested reading: &lt;em&gt;CLRS&lt;/em&gt;, Sedgewick’s &lt;em&gt;Algorithms&lt;/em&gt;, and &lt;em&gt;Problem Solving with Algorithms and Data Structures&lt;/em&gt; by Miller &amp;amp; Ranum.&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>