Algorithms & data structures project
Algorithms and data structures are fundamental to efficient code and good software design. Creating and designing excellent algorithms is required for being an exemplary programmer. This repository's goal is to demonstrate how to correctly implement common data structures and algorithms in the simplest and most elegant ways.
Contributing
This repository is contribution friendly
Other programming languages?
This repository provides algorithm implementations in Java, however there are other forks that provide implementations in other languages, most notably:
Running an algorithm implementation
To compile and run any of the algorithms here, you need at least JDK version 8. Gradle can make things more convenient for you, but it is not required.
Running with Gradle (recommended)
This project supports the Gradle Wrapper. The Gradle wrapper automatically downloads Gradle at the first time it runs, so expect a delay when running the first command below.
If you are on Windows, use gradlew.bat
instead of ./gradlew
below.
Run a single algorithm like this:
./gradlew run -Palgorithm=<algorithm-subpackage>.<algorithm-class>
Alternatively, you can run a single algorithm specifying the full class name
./gradlew run -Pmain=<algorithm-fully-qualified-class-name>
For instance:
./gradlew run -Palgorithm=search.BinarySearch
or
./gradlew run -Pmain=com.williamfiset.algorithms.search.BinarySearch
Compiling and running with only a JDK
Create a classes folder
cd Algorithms
mkdir classes
Compile the algorithm
javac -sourcepath src/main/java -d classes src/main/java/ <relative-path-to-java-source-file>
Run the algorithm
java -cp classes <class-fully-qualified-name>
Example
$ javac -d classes -sourcepath src/main/java src/main/java/com/williamfiset/algorithms/search/BinarySearch.java
$ java -cp classes com.williamfiset.algorithms.search.BinarySearch
Data Structures
🎥 Balanced Trees🎥 Binary Search Tree- Splay Tree
🎥 Dynamic Array🎥 Fenwick Tree- Fibonacci Heap
🎥 Hashtable🎥 Linked List🎥 Priority Queue🎥 Queue- Segment Tree
🎥 Sparse Table🎥 Stack🎥 Suffix Array- Trie
🎥 Union Find
Dynamic Programming
Dynamic Programming Classics
- Coin change problem - O(nW)
- Edit distance (iterative) - O(nm)
- Edit distance (recursive) - O(nm)
🎥 Knapsack 0/1 - O(nW)- Knapsack unbounded (0/∞) - O(nW)
- Maximum contiguous subarray - O(n)
- Longest Common Subsequence (LCS) - O(nm)
- Longest Increasing Subsequence (LIS) - O(n2)
- Longest Palindrome Subsequence (LPS) - O(n2)
🎥 Traveling Salesman Problem (dynamic programming, iterative) - O(n22n)- Traveling Salesman Problem (dynamic programming, recursive) - O(n22n)
- Minimum Weight Perfect Matching (iterative, complete graph) - O(n22n)
Dynamic Programming Problem Examples
Adhoc
Tiling problems
Geometry
- Angle between 2D vectors - O(1)
- Angle between 3D vectors - O(1)
- Circle-circle intersection point(s) - O(1)
- Circle-line intersection point(s) - O(1)
- Circle-line segment intersection point(s) - O(1)
- Circle-point tangent line(s) - O(1)
- Closest pair of points (line sweeping algorithm) - O(nlog(n))
- Collinear points test (are three 2D points on the same line) - O(1)
- Convex hull (Graham Scan algorithm) - O(nlog(n))
- Convex hull (Monotone chain algorithm) - O(nlog(n))
- Convex polygon area - O(n)
- Convex polygon cut - O(n)
- Convex polygon contains points - O(log(n))
- Coplanar points test (are four 3D points on the same plane) - O(1)
- Line class (handy infinite line class) - O(1)
- Line-circle intersection point(s) - O(1)
- Line segment-circle intersection point(s) - O(1)
- Line segment to general form (ax + by = c) - O(1)
- Line segment-line segment intersection - O(1)
- Longitude-Latitude geographic distance - O(1)
- Point is inside triangle check - O(1)
- Point rotation about point - O(1)
- Triangle area algorithms - O(1)
- [UNTESTED] Circle-circle intersection area - O(1)
- [UNTESTED] Circular segment area - O(1)
Graph theory
Tree algorithms
🎥 Rooting an undirected tree - O(V+E)🎥 Identifying isomorphic trees - O(?)🎥 Tree center(s) - O(V+E)- Tree diameter - O(V+E)
🎥 Lowest Common Ancestor (LCA, Euler tour) - O(1) queries, O(nlogn) preprocessing
Network flow
- Bipartite graph verification (adjacency list) - O(V+E)
🎥 Max flow & Min cut (Ford-Fulkerson with DFS, adjacency list) - O(fE)- Max flow & Min cut (Ford-Fulkerson with DFS, adjacency matrix) - O(fV2)
🎥 Max flow & Min cut (Edmonds-Karp, adjacency list) - O(VE2)🎥 Max flow & Min cut (Capacity scaling, adjacency list) - O(E2log2(U))🎥 Max flow & Min cut (Dinic's, adjacency list) - O(EV2) or O(E√V) for bipartite graphs- Maximum Cardinality Bipartite Matching (augmenting path algorithm, adjacency list) - O(VE)
- Min Cost Max Flow (Bellman-Ford, adjacency list) - O(E2V2)
- Min Cost Max Flow (Johnson's algorithm, adjacency list) - O(E2Vlog(V))
Main graph theory algorithms
- Articulation points/cut vertices (adjacency list) - O(V+E)
- Bellman-Ford (edge list, negative cycles, fast & optimized) - O(VE)
🎥 Bellman-Ford (adjacency list, negative cycles) - O(VE)- Bellman-Ford (adjacency matrix, negative cycles) - O(V3)
🎥 Breadth first search (adjacency list) - O(V+E)- Breadth first search (adjacency list, fast queue) - O(V+E)
- Bridges/cut edges (adjacency list) - O(V+E)
- Find connected components (adjacency list, union find) - O(Elog(E))
- Find connected components (adjacency list, DFS) - O(V+E)
- Depth first search (adjacency list, iterative) - O(V+E)
- Depth first search (adjacency list, iterative, fast stack) - O(V+E)
🎥 Depth first search (adjacency list, recursive) - O(V+E)🎥 Dijkstra's shortest path (adjacency list, lazy implementation) - O(Elog(V))🎥 Dijkstra's shortest path (adjacency list, eager implementation + D-ary heap) - O(ElogE/V(V))🎥 Eulerian Path (directed edges) - O(E+V)🎥 Floyd Warshall algorithm (adjacency matrix, negative cycle check) - O(V3)- Graph diameter (adjacency list) - O(VE)
🎥 Kahn's algorithm (topological sort, adjacency list) - O(E+V)- Kruskal's min spanning tree algorithm (edge list, union find) - O(Elog(E))
🎥 Kruskal's min spanning tree algorithm (edge list, union find, lazy sorting) - O(Elog(E))- Kosaraju's strongly connected components algorithm (adjacency list) - O(V+E)
🎥 Prim's min spanning tree algorithm (lazy version, adjacency list) - O(Elog(E))- Prim's min spanning tree algorithm (lazy version, adjacency matrix) - O(V2)
🎥 Prim's min spanning tree algorithm (eager version, adjacency list) - O(Elog(V))- Steiner tree (minimum spanning tree generalization) - O(V3 + V2 _ 2T + V _ 3T)
🎥 Tarjan's strongly connected components algorithm (adjacency list) - O(V+E)🎥 Topological sort (acyclic graph, adjacency list) - O(V+E)- Topological sort (acyclic graph, adjacency matrix) - O(V2)
- Traveling Salesman Problem (brute force) - O(n!)
🎥 Traveling Salesman Problem (dynamic programming, iterative) - O(n22n)- Traveling Salesman Problem (dynamic programming, recursive) - O(n22n)
Linear algebra
- Freivald's algorithm (matrix multiplication verification) - O(kn2)
- Gaussian elimination (solve system of linear equations) - O(cr2)
- Gaussian elimination (modular version, prime finite field) - O(cr2)
- Linear recurrence solver (finds nth term in a recurrence relation) - O(m3log(n))
- Matrix determinant (Laplace/cofactor expansion) - O((n+2)!)
- Matrix inverse - O(n3)
- Matrix multiplication - O(n3)
- Matrix power - O(n3log(p))
- Square matrix rotation - O(n2)
Mathematics
- [UNTESTED] Chinese remainder theorem
- Prime number sieve (sieve of Eratosthenes) - O(nlog(log(n)))
- Prime number sieve (sieve of Eratosthenes, compressed) - O(nlog(log(n)))
- Totient function (phi function, relatively prime number count) - O(n1/4)
- Totient function using sieve (phi function, relatively prime number count) - O(nlog(log(n)))
- Extended euclidean algorithm - ~O(log(a + b))
- Greatest Common Divisor (GCD) - ~O(log(a + b))
- Fast Fourier transform (quick polynomial multiplication) - O(nlog(n))
- Fast Fourier transform (quick polynomial multiplication, complex numbers) - O(nlog(n))
- Primality check - O(√n)
- Primality check (Rabin-Miller) - O(k)
- Least Common Multiple (LCM) - ~O(log(a + b))
- Modular inverse - ~O(log(a + b))
- Prime factorization (pollard rho) - O(n1/4)
- Relatively prime check (coprimality check) - ~O(log(a + b))
Other
- Bit manipulations - O(1)
- List permutations - O(n!)
🎥 Power set (set of all subsets) - O(2n)- Set combinations - O(n choose r)
- Set combinations with repetition - O((n+r-1) choose r)
- Sliding Window Minimum/Maximum - O(1)
- Square Root Decomposition - O(1) point updates, O(√n) range queries
- Unique set combinations - O(n choose r)
- Lazy Range Adder - O(1) range updates, O(n) to finalize all updates
Search algorithms
- Binary search (real numbers) - O(log(n))
- Interpolation search (discrete discrete) - O(n) or O(log(log(n))) with uniform input
- Ternary search (real numbers) - O(log(n))
- Ternary search (discrete numbers) - O(log(n))
Sorting algorithms
- Bubble sort - O(n2)
- Bucket sort - Θ(n + k)
- Counting sort - O(n + k)
- Heapsort - O(nlog(n))
- Insertion sort - O(n2)
- Mergesort - O(nlog(n))
- Quicksort (in-place, Hoare partitioning) - Θ(nlog(n))
- Quicksort3 (Dutch National Flag algorithm) - Θ(nlog(n))
- Selection sort - O(n2)
- Radix sort - O(n*w)
String algorithms
- Booth's algorithm (finds lexicographically smallest string rotation) - O(n)
- Knuth-Morris-Pratt algorithm (finds pattern matches in text) - O(n+m)
- Longest Common Prefix (LCP) array - O(nlog(n)) bounded by SA construction, otherwise O(n)
🎥 Longest Common Substring (LCS) - O(nlog(n)) bounded by SA construction, otherwise O(n)🎥 Longest Repeated Substring (LRS) - O(nlog(n))- Manacher's algorithm (finds all palindromes in text) - O(n)
- Rabin-Karp algorithm (finds pattern match positions in text) - O(n+m)
- Substring verification with suffix array - O(nlog(n)) SA construction and O(mlog(n)) per query
License
This repository is released under the MIT license. In short, this means you are free to use this software in any personal, open-source or commercial projects. Attribution is optional but appreciated.
Donate
Consider donating to support my creation of educational content: