A structured repository dedicated to implementing, analyzing, and documenting foundational computer science algorithms and data structures using Python. This project serves as an educational sandbox to study runtime complexities, data architecture, and verification methodologies.
src/: Core Python implementations categorized by algorithmic domain.service/: Transport-agnostic wrappers exposing the algorithms via an MCP stdio server and a FastAPI HTTP API.tests/: Automated unit tests mirroring the codebase layout to validate edge cases and performance boundaries.docs/adr/: Architectural Decision Records tracking the design choices for each algorithm.docs/CONTRIBUTING.md: Step-by-step branching, testing, and PR/merge workflow guide.
- Python 3.10 or higher
- pip (Python package installer)
-
Clone the repository:
git clone https://github.com cd csc-algorithms -
Initialize a local virtual environment:
python -m venv venv source venv/bin/activate # On Windows use: venv\Scripts\activate
-
Install required development and testing dependencies:
pip install -r requirements.txt
The repository uses pytest for codebase verification. Run the test suite globally using the following command:
pytest tests/To run syntax and style validation checks using flake8 or black:
black --check src/ tests/For the full test and coverage gate, run make verify. Local commits use the tracked .githooks/pre-commit hook for fast staged-area tests by default; use TEST_SCOPE=full git commit to run the complete 100% coverage gate before committing.
Every algorithm is also exposed via a stateless MCP server and a REST API, both backed by the same service/tools.py wrapper functions.
MCP server (stdio transport) — for use with MCP-aware agents/chat clients (Claude Desktop, VS Code, etc.):
python -m service.mcp_serverRegister it with your MCP client by pointing it at this command; consult your client's documentation for its mcp.json/config format.
HTTP API — for any other programmatic caller:
uvicorn service.http_app:app --reloadEach endpoint mirrors an MCP tool, e.g. POST /sorting/quicksort, POST /graphs/dijkstra, POST /machine-learning/kmeans. Interactive OpenAPI docs are available at http://127.0.0.1:8000/docs once the server is running.
The architectural choices, trade-offs, and design patterns for each algorithm are fully documented below:
- ADR 0000: Expose Algorithms via MCP and HTTP Service Layer
- ADR 0001: Hoare Partitioning for Quicksort
- ADR 0002: heapq for Dijkstra Priority Queue
- ADR 0003: LPS Array for KMP String Matching
- ADR 0004: Recursive Node-Pointer Binary Search Tree
- ADR 0005: NumPy Vectorized K-Means Clustering
- ADR 0006: NumPy eigh Covariance PCA
- ADR 0007: Edge-List Relaxation for Bellman-Ford
- ADR 0008: Euclidean Heuristic for A* Pathfinding
- ADR 0009: AVL Rotations for Self-Balancing BST
- ADR 0010: Min-Heap Greedy Merge for Huffman Coding
- ADR 0011: Kahn's In-Degree BFS for Topological Sort
- ADR 0012: Iterative Boolean Marking for Sieve of Eratosthenes
- ADR 0013: Union by Rank with Path Compression for Union-Find
- ADR 0014: Bottom-Up Divide-and-Conquer Merge for Merge Sort
- ADR 0015: Iterative Pointer Rewiring for Singly Linked List Reversal
- ADR 0016: Bottom-Up Tabulation with Backtracking for 0/1 Knapsack
- ADR 0017: Bottom-Up Tabulation with Diagonal Backtracking for LCS
- ADR 0018: Binary Max-Heap for Heap Sort
- ADR 0019: Iterative Midpoint Bisection for Binary Search
- ADR 0020: Iterative Queue and Stack for BFS and DFS
- ADR 0021: Edge-Sorted Union-Find for Kruskal's Algorithm
- ADR 0022: Character-Branching Trie for Prefix Lookups
- ADR 0023: Iterative Euclidean GCD
- ADR 0024: Stack for Valid Parentheses
Browse the algorithm catalog for concise definitions, complexity notes, implementation links, tests, and guidance on choosing an algorithm or data structure.
To ensure uniformity, this repository follows strict standards derived from PEP 8:
- Functions & Variables: Lowercase word blocks separated by underscores (
snake_case). - Protected Components: Preceded by a single leading underscore (e.g.,
_partition). - Constants: Full uppercase strings separated by underscores (
UPPER_SNAKE_CASE). - Type Hinting: Mandatory on all public functions via the
typingmodule framework.
-
Input Integrity & Memory Protection: Sorting algorithms construct a explicit local
list()copy of tracking variables to prevent input reference mutation bugs. -
Denial of Service (DoS) Boundaries: Quicksort worst-case scaling behavior is
$O(n^2)$ . For safety-critical systems sorting untrusted or adversarial user inputs, randomizing the pivot selection or utilizingheap-sort/merge-sortderivatives should be considered. -
Graph Payload Resilience: The Dijkstra parser explicitly references data isolation using explicit
float("inf")typing arrays. Node configurations must strictly pass hashable unique strings to mitigate graph processing collision events. - Data Isolation: This package operates entirely locally on internal operational states. No logging pipelines, web tracing, or environment data tracking hooks are implemented, ensuring maximum data privacy.
-
Negative-Weight Cycle Guarding: The Bellman-Ford implementation runs an explicit final relaxation pass to detect reachable negative-weight cycles and raises a
ValueErrorrather than allowing an untrusted graph payload to loop indefinitely. - Heuristic Input Validation: The A* implementation validates that source, target, and coordinate metadata exist before search begins, and rejects negative edge weights, preventing malformed spatial graphs from corrupting the heuristic scoring.
- Balanced Depth Guarantee: The AVL Tree rebalances on every insert and delete, preventing adversarial sorted-input sequences from degrading traversal operations to linear time.
-
Codebook Integrity Validation: The Huffman decoder rejects malformed or duplicate-code codebooks and dangling/invalid bitstreams with an explicit
ValueError, rather than silently returning corrupted or truncated text. -
Cycle & Referential Integrity Guards: Topological Sort validates that every edge references a declared node and raises a
ValueErrorwhen a cycle prevents a complete ordering, rather than silently returning a partial or misleading sequence. - Bounded Memory Allocation: The Sieve of Eratosthenes allocates its boolean tracking array based on the caller-supplied boundary; callers should validate untrusted boundary inputs against a sane upper limit before use to avoid excessive memory allocation.
-
Service Layer Input Validation: The HTTP API validates request bodies via Pydantic schemas and translates algorithm-level
ValueErrors into HTTP 400 responses rather than leaking stack traces; both the MCP server and HTTP API are stateless per call, so no client-supplied data persists across requests. -
Fixed Element Universe: Union-Find validates every
find()/union()call against its initial element set and raises aValueErrorfor unknown elements, preventing silent creation of untracked entries. -
Worst-Case DoS Mitigation: Merge Sort guarantees
$O(n \log n)$ even on adversarial input, making it the safer default over Quicksort when sorting untrusted, attacker-influenced data where worst-case scaling matters. -
Bounded Traversal Footprint: The Singly Linked List's
search/delete/reverseoperations are strictly O(n) iterative walks with no recursion, preventing stack-depth exhaustion on very large untrusted input lists. -
Iterative DP, No Recursion Limits: The 0/1 Knapsack solver uses bottom-up tabulation rather than top-down recursion, avoiding Python's
RecursionErroron large item counts. -
Quadratic Complexity Awareness: LCS runs in
$O(n \times m)$ time and space; callers should bound input string lengths when comparing untrusted, attacker-controlled text to avoid excessive memory allocation on very large inputs. -
In-Place Worst-Case Guarantee: Heap Sort provides the same
$O(n \log n)$ worst-case guarantee as Merge Sort but with$O(1)$ auxiliary space, useful when both adversarial-input resilience and memory constraints matter simultaneously. - Precondition Responsibility: Binary Search assumes sorted input and does not validate it; callers must guarantee sortedness themselves, since verifying it would negate the algorithm's logarithmic performance advantage.
- Traversal Input Integrity: BFS and DFS validate the source and every adjacency reference before traversal, preventing malformed graph payloads from producing partial results; both use iterative state to avoid recursion-depth exhaustion.
- Minimum-Spanning-Tree Integrity: Kruskal validates vertex and edge references, skips cycle-forming edges with Union-Find, and rejects disconnected graphs instead of returning a partial spanning tree.