A comprehensive collection of fundamental algorithms, data structures, and design patterns implemented in Python and TypeScript. Perfect for learning, interviews, and reference.
- Sorting Algorithms
- Searching Algorithms
- Graph Algorithms
- String Algorithms
- Optimization Algorithms
- Data Structures
- Design Patterns
- CS Concepts
- Big O Notation
Sorting algorithms arrange elements in a specific order. Here's a visual comparison:
Input: [64, 34, 25, 12, 22, 11, 90]
Bubble Sort: [64,34,25,12,22,11,90] โ Compare & swap adjacent elements
[34,64,25,12,22,11,90] โ Repeat until sorted
...
[11,12,22,25,34,64,90] โ
Quick Sort: [64,34,25,12,22,11,90]
โ Pick pivot (64)
[34,25,12,22,11] | 64 | [90]
โ Recursively sort
[11,12,22,25,34] | 64 | [90] โ
| Algorithm | Best | Average | Worst | Space | Stable | File |
|---|---|---|---|---|---|---|
| Bubble Sort | O(n) | O(nยฒ) | O(nยฒ) | O(1) | โ | bubble_sort.py |
| Selection Sort | O(nยฒ) | O(nยฒ) | O(nยฒ) | O(1) | โ | selection_sort.py |
| Insertion Sort | O(n) | O(nยฒ) | O(nยฒ) | O(1) | โ | insertion_sort.py |
| Merge Sort | O(n log n) | O(n log n) | O(n log n) | O(n) | โ | merge_sort.py |
| Quick Sort | O(n log n) | O(n log n) | O(nยฒ) | O(log n) | โ | quick_sort.py |
| Heap Sort | O(n log n) | O(n log n) | O(n log n) | O(1) | โ | heap_sort.py |
| Counting Sort | O(n+k) | O(n+k) | O(n+k) | O(k) | โ | counting_sort.py |
| Radix Sort | O(d(n+k)) | O(d(n+k)) | O(d(n+k)) | O(n+k) | โ | radix_sort.py |
| Bucket Sort | O(n+k) | O(n+k) | O(nยฒ) | O(n+k) | โ | bucket_sort.py |
| Shell Sort | O(n log n) | O(n^1.5) | O(nยฒ) | O(1) | โ | shell_sort.py |
| Comb Sort | O(n log n) | O(nยฒ/2^p) | O(nยฒ) | O(1) | โ | comb_sort.py |
| Intro Sort | O(n log n) | O(n log n) | O(n log n) | O(log n) | โ | intro_sort.py |
[64, 34, 25, 12, 22, 11, 90]
/ \
[64, 34, 25, 12] [22, 11, 90]
/ \ / \
[64, 34] [25, 12] [22, 11] [90]
/ \ / \ / \ |
[64] [34] [25] [12] [22] [11] [90]
\ / \ / \ / |
[34, 64] [12, 25] [11, 22] [90]
\ / \ /
[12, 25, 34, 64] [11, 22, 90]
\ /
[11, 12, 22, 25, 34, 64, 90] โ
Linear Search: [1, 3, 5, 7, 9, 11, 13] Find: 7
โ โ โ โ โ Found at index 3
O(n) - checks each element
Binary Search: [1, 3, 5, 7, 9, 11, 13] Find: 7
โ โ โ
low mid high
[1,3,5,7] โ 7 is here
[5,7] โ 7 is here
[7] โ Found!
O(log n) - halves search space
| Algorithm | Best | Average | Worst | Space | File |
|---|---|---|---|---|---|
| Linear Search | O(1) | O(n) | O(n) | O(1) | linear_search.py |
| Binary Search | O(1) | O(log n) | O(log n) | O(1) | binary_search.py |
| Breadth-First Search | O(V+E) | O(V+E) | O(V+E) | O(V) | breadth_first_search.py |
| Depth-First Search | O(V+E) | O(V+E) | O(V+E) | O(V) | depth_first_search.py |
| A* Search | O(b^d) | O(b^d) | O(b^d) | O(b^d) | a_star.py |
| Iterative Deepening | O(b^d) | O(b^d) | O(b^d) | O(bd) | iterative_deepening_search.py |
| Uniform Cost Search | O((V+E)log V) | O((V+E)log V) | O((V+E)log V) | O(V) | uniform_cost_search.py |
BFS (Level by level): DFS (Deep first):
A A
/ \ / \
B C B C
/ \ \ / / \
D E F D E F
BFS Order: A โ B โ C โ D โ E โ F
DFS Order: A โ B โ D โ E โ C โ F
Graph: Dijkstra's (from A): Bellman-Ford (from A):
Aโ4โB A: 0 A: 0
โ โ B: 4 B: 4
2 5 C: 2 C: 2
โ โ D: 9 D: 9
Cโ1โD E: 12 E: 12
\ /
10
E
| Algorithm | Time Complexity | Space | Handles Negative Weights | File |
|---|---|---|---|---|
| Dijkstra's | O((V+E) log V) | O(V) | โ | dijkstra.py |
| Bellman-Ford | O(VE) | O(V) | โ | bellman_ford.py |
| Floyd-Warshall | O(Vยณ) | O(Vยฒ) | โ | floyd_warshall.py |
| A* | O(b^d) | O(b^d) | โ | a_star.py |
Original Graph: Kruskal's MST: Prim's MST:
Aโ4โB Aโ4โB Aโ4โB
โ\ โ\ โ โ โ โ
2โ โโ5 2 โ5 2 โ5
โ \โโ โ โ โ โ
Cโ1โD Cโ1โD Cโ1โD
\ / \ / \ /
10 10 10
E E E
| Algorithm | Time Complexity | File |
|---|---|---|
| Kruskal's MST | O(E log E) | kruskal_mst.py |
| Prim's MST | O(E log V) | prim_mst.py |
- Connected Components -
connected_components.py - Graph Coloring -
graph_coloring.py - Topological Sort -
topological_sort.py - Max Flow / Min Cut -
max_flow_min_cut.py
Text: "ABABDABACDABABCABCAB"
Pattern: "ABABCABAB"
KMP: Uses failure function to skip characters
ABABCABAB
โโโ (match prefix "AB")
On mismatch, skip to next possible match
Rabin-Karp: Uses rolling hash
Hash(pattern) = hash("ABABCABAB")
Compare hash of each substring
If hash matches, verify actual match
| Algorithm | Time Complexity | Space | File |
|---|---|---|---|
| KMP | O(n + m) | O(m) | kmp_string_matching.py |
| Rabin-Karp | O(n + m) avg, O(nm) worst | O(1) | rabin_karp.py |
Temperature: 1000ยฐ โ 500ยฐ โ 250ยฐ โ 125ยฐ โ ...
โ โ โ โ
Acceptance: High โ Medium โ Low โ Very Low
โ โ โ โ
Exploration: Wide โ Narrow โ Fine โ Local
| Algorithm | Use Case | File |
|---|---|---|
| Simulated Annealing | Global optimization, TSP | simulated_annealing.py |
| Hill Climbing | Local optimization | hill_climbing.py |
| Genetic Algorithm | Evolutionary optimization | GeneticAlgorithm.py |
Array: [1, 2, 3, 4, 5]
O(1) access, O(n) insert/delete
Linked List: 1 โ 2 โ 3 โ 4 โ 5
O(n) access, O(1) insert/delete
Stack: [Top] 3
โ 2
โ 1
LIFO (Last In, First Out)
Queue: 1 โ 2 โ 3 โ [Front]
FIFO (First In, First Out)
Binary Tree: 5
/ \
3 7
/ \ / \
2 4 6 8
Hash Table: Key โ Hash โ Index โ Value
"apple" โ hash โ 3 โ "red"
O(1) average lookup
| Data Structure | Access | Search | Insert | Delete | File |
|---|---|---|---|---|---|
| Array | O(1) | O(n) | O(n) | O(n) | array.py |
| Linked List | O(n) | O(n) | O(1) | O(1) | linked_list.py |
| Stack | O(1) | O(n) | O(1) | O(1) | stack.py |
| Queue | O(1) | O(n) | O(1) | O(1) | queue.py |
| Binary Tree | O(n) | O(n) | O(n) | O(n) | binary_tree.py |
| BST | O(log n) | O(log n) | O(log n) | O(log n) | binary_search_tree.py |
| Heap | O(1) | O(n) | O(log n) | O(log n) | heap.py |
| Hash Table | O(1) | O(1) | O(1) | O(1) | hash_table.py |
| Trie | O(m) | O(m) | O(m) | O(m) | trie.py |
| Graph | O(V+E) | O(V+E) | O(1) | O(V+E) | graph.py |
Creational Patterns Structural Patterns Behavioral Patterns
โโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
โ Singleton โ โ Adapter โ โ Observer โ
โ Factory โ โ Decorator โ โ Strategy โ
โ Builder โ โ Facade โ โ Command โ
โ Prototype โ โ Proxy โ โ Iterator โ
โAbstract Factโ โ Bridge โ โ State โ
โ โ โ Composite โ โ Visitor โ
โ โ โ Flyweight โ โ Mediator โ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ Memento โ
โ Template โ
โ Chain of โ
โResponsibilityโ
โโโโโโโโโโโโโโโ
| Pattern | Purpose | File |
|---|---|---|
| Singleton | Single instance | singleton.py |
| Factory | Object creation | factory_method.py |
| Observer | Event notification | observer.py |
| Strategy | Algorithm selection | strategy.py |
| Decorator | Add behavior dynamically | decorator.py |
See Design Patterns README for complete list.
Modern software development concepts with TypeScript examples:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ TypeScript Concepts โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ Interfaces & Types โ
โ โ Generics & Constraints โ
โ โ Async/Await & Promises โ
โ โ Functional Programming โ
โ โ Type Guards & Utilities โ
โ โ Design Patterns in TS โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- Interfaces -
interfaces.ts - Types & Generics -
types_and_generics.ts - Async/Promises -
async_promises.ts - Functional Programming -
functional_programming.ts - Type Guards -
type_guards_and_utilities.ts - Design Patterns -
design_patterns_typescript.ts
See CS Concepts README for details.
Understanding algorithm efficiency:
Complexity Name Example Operations
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
O(1) Constant Array access, hash lookup
O(log n) Logarithmic Binary search, tree operations
O(n) Linear Linear search, array iteration
O(n log n) Linearithmic Merge sort, heap sort
O(nยฒ) Quadratic Bubble sort, nested loops
O(2โฟ) Exponential Recursive Fibonacci
O(n!) Factorial Permutations
Operations
โ
โ O(n!)
โ โฑ
โ โฑ
โ โฑ O(2โฟ)
โโฑ
โโโโโโ O(nยฒ)
โ โฒ
โ โฒ O(n log n)
โ โฒ
โ โฒ O(n)
โ โฒ
โ โฒ O(log n)
โ โฒ
โ โฒ O(1)
โโโโโโโโโโโโดโโโโโโโโโโโ Input Size
Resources:
All of these describe how runtime (or steps) grows as input size n grows. The key difference is the shape of that growth curve โ not the exact constant factors.
Think of n as โhow much data you have.โ As n gets huge, only the dominant term matters.
Growth: Does not grow with n. Same cost whether you have 10 items or 10 million.
Difference: The only class where doubling data does not increase work (for that single operation).
Example: Hash map get by key (average case) โ compute hash, jump to bucket, read value.
n = 1 โ ~1 step
n = 1,000,000 โ ~1 step
Growth: Grows very slowly. Each step shrinks the problem (usually by half).
Difference from O(1): Still depends on n, but weakly โ adding one more step when you double n.
Example: Binary search in a sorted array.
n = 1,000 โ ~10 comparisons
n = 1,000,000 โ ~20 comparisons (1000ร more data, only ~2ร work)
vs O(1): O(log n) is โalmost constantโ for practical sizes, but technically still tied to n.
Growth: Work grows in proportion to n. Double the data โ roughly double the time.
Difference from O(log n): You typically touch every item once (or a fixed fraction of them), not repeatedly cut the problem in half.
Example: Find max in an unsorted array โ one pass.
n = 1,000 โ ~1,000 steps
n = 1,000,000 โ ~1,000,000 steps
Rule of thumb: One loop over n โ often O(n).
Growth: Faster than linear, slower than quadratic. Common for efficient sorting and โdivide, solve small pieces, combineโ algorithms.
Difference from O(n): You do O(n) work at each of O(log n) levels (typical divide-and-conquer pattern).
Example: Merge sort, heap sort.
n = 1,000 โ ~10,000 operations (1000 ร logโ 1000 โ 10k)
n = 1,000,000 โ ~20,000,000 (1M ร 20)
vs O(nยฒ): For large n, n log n is much cheaper than nยฒ.
| n | n log n (rough) | nยฒ |
|---|---|---|
| 1,000 | ~10k | ~1M |
| 10,000 | ~130k | ~100M |
Growth: If you double n, work roughly quadruples (4ร).
Difference from O(n): Often nested loops โ for each of n items, you do something with all n again.
Example: Bubble sort, naive โcompare every pair.โ
for i in range(n):
for j in range(n):
...n = 1,000 โ ~1,000,000 steps
n = 1,000,000 โ ~1,000,000,000,000 steps (impractical)
vs O(n log n): Sorting 1M items: merge sort ~20M ops vs naive O(nยฒ) ~1 trillion ops.
| Complexity | 10ร more data (n โ 10n) |
Feels like |
|---|---|---|
| O(1) | Same | Instant |
| O(log n) | +~3 steps (base 2) | Barely notice |
| O(n) | ~10ร slower | Scales with data |
| O(n log n) | ~10ร + a bit more (log factor) | Fine for big data |
| O(nยฒ) | ~100ร slower | Dies on large n |
cost
โ
โ โฑ O(nยฒ)
โ โฑ
โ โฑ O(n log n)
โ โฑ
โ โฑ O(n)
โ โฑ
โโฑ O(log n) (stays very flat)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ O(1) (flat line)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ n
| Pattern | Typical complexity |
|---|---|
Single lookup, no loop over n |
O(1) |
| Halve/search tree each step | O(log n) |
One loop over n |
O(n) |
| Sort efficiently (merge/heap) | O(n log n) |
Two nested loops over n |
O(nยฒ) |
Important: Big-O ignores constants. O(1000n) is still O(n). O(n) with a tiny n can beat O(log n) with huge overhead in practice โ but as n grows, the class wins.
- O(1): Size doesnโt matter for that operation.
- O(log n): Repeatedly cut the problem in half.
- O(n): Do something once per item.
- O(n log n): Do โper itemโ work across log-many layers (smart divide-and-conquer).
- O(nยฒ): Every item interacts with every other item (nested loops).
If you want, we can walk through one concrete algorithm (e.g. linear search vs binary search vs bubble sort) step-by-step with n = 8 so the counts are explicit.
- Fibonacci -
fibonacci.py- Multiple implementations (recursive, iterative, memoized) - GCD/LCM -
gcd_lcm.py- Euclidean algorithm - Sieve of Eratosthenes -
sieve_of_eratosthenes.py- Prime number generation - Integer Partition -
integer_partition.py- Combinatorics - Caesar Cipher -
caesar_cipher.py- Basic encryption
- Union-Find -
union_find.py- Disjoint set union - Page Rank -
page_rank.ipynb- Web page ranking - Catalan Numbers -
calatan_numbers.ipynb- Combinatorial sequence
# Run any algorithm file
python Algorithms/bubble_sort.py
# Or import in your code
from Algorithms.bubble_sort import bubble_sort
arr = [64, 34, 25, 12, 22, 11, 90]
bubble_sort(arr)
print(arr) # [11, 12, 22, 25, 34, 64, 90]# Install TypeScript
npm install -g typescript
# Compile TypeScript files
tsc CS\ Concepts/interfaces.ts
# Or use with a bundlerfrom Data_Structures.linked_list import LinkedList
ll = LinkedList()
ll.append(1)
ll.append(2)
ll.append(3)
print(ll) # 1 -> 2 -> 3- Start with Linear Search and Bubble Sort
- Learn Arrays and Linked Lists
- Understand Stack and Queue
- Master Binary Search and Quick Sort
- Learn Trees and Hash Tables
- Study BFS and DFS
- Implement Graph Algorithms (Dijkstra, MST)
- Master Dynamic Programming
- Study Design Patterns
Contributions are welcome! Please ensure:
- Code follows existing style
- Includes proper documentation
- Has example usage
- Time/space complexity noted
