This project implements the Ford-Johnson Algorithm (also known as merge-insertion sort), a comparison-based sorting algorithm that achieves the minimum number of comparisons for small input sizes. The implementation uses both std::vector and std::deque containers to demonstrate the algorithm's behavior across different data structures.
The Ford-Johnson algorithm, discovered by Lester R. Ford Jr. and Selmer M. Johnson in 1959, is historically significant as it was the first algorithm to sort n elements with fewer than the information-theoretic minimum number of comparisons required by merge sort.
- Binary Insertion: Uses binary search to find insertion points, minimizing comparisons
- Jacobsthal Numbers: Employs a specific insertion sequence based on Jacobsthal numbers (1, 3, 5, 11, 21, 43, 85...)
- Optimal Ordering: Strategically pairs and orders elements to minimize total comparisons
- β
Dual Implementation: Supports both
std::vectorandstd::deque - β C++98 Compliant: Written in standard C++98 for maximum compatibility
- β Optimal Comparisons: Achieves theoretical minimum comparisons for small datasets
- β Input Validation: Robust error handling and duplicate detection
- β Performance Metrics: Displays comparison counts and execution time
- β Large Dataset Support: Handles thousands of elements efficiently
The Ford-Johnson algorithm is provably optimal for certain input sizes. For example:
| Elements (n) | Min Comparisons | FJ Comparisons | Status |
|---|---|---|---|
| 21 | 66 | 66 | β Optimal |
| 22 | 71 | 71 | β Optimal |
| 10 | 22 | 22 | β Optimal |
| 11 | 26 | 26 | β Optimal |
For n = 21 elements, the information-theoretic lower bound is:
βlogβ(21!)β β 60.09 comparisons
However, accounting for practical constraints and the structure of comparison-based sorting, the Ford-Johnson algorithm achieves exactly 66 comparisons, which is the minimum possible for this input size using this approach.
- C++ compiler with C++98 support
- Make utility
# Clone the repository
git clone https://github.com/ITAXBOX/Ford-Johnson-Algorithm.git
cd Ford-Johnson-Algorithm
# Compile the project
make
# Clean build artifacts
make clean
# Rebuild from scratch
make re./FordJohnson <number1> <number2> <number3> ..../FordJohnson 5 2 9 1 7 3./FordJohnson `shuf -i 1-100000 -n 21 | tr "\n" " "`./FordJohnson `shuf -i 1-100000 -n 3000 | tr "\n" " "`./FordJohnson $(seq 1 21 | shuf | tr "\n" " ")Before: 5 2 9 1 7 3
After: 1 2 3 5 7 9
Vector: 9 comparisons, 0.000234 seconds
Deque: 9 comparisons, 0.000187 seconds
The algorithm consistently achieves optimal comparison counts:
# Test 1: Exactly 21 elements
$ ./FordJohnson `shuf -i 1-100000 -n 21 | tr "\n" " "`
Vector: 66 comparisons # Always 66!
Deque: 66 comparisons # Always 66!
# Test 2: Different random set
$ ./FordJohnson `shuf -i 1-100000 -n 21 | tr "\n" " "`
Vector: 66 comparisons # Still 66!
Deque: 66 comparisons # Still 66!The algorithm handles large datasets efficiently:
| Elements | Comparisons (Approx.) | Time (Approx.) |
|---|---|---|
| 10 | 22 | < 0.001s |
| 21 | 66 | < 0.001s |
| 100 | ~543 | < 0.01s |
| 1000 | ~8,530 | ~0.05s |
| 3000 | ~31,000 | ~0.15s |
- Pairing Phase: Elements are paired and sorted within pairs
- Recursive Sort: Pairs are recursively sorted by their larger elements
- Main Chain Formation: Create the main sorted chain from larger elements
- Jacobsthal Insertion: Insert smaller elements using Jacobsthal sequence ordering
- Binary Search: Use binary search to find optimal insertion positions
mergeInsertSortVector(): Main sorting logicperformInsertionSortVector(): Handles the insertion phasebinarySearchPositionVector(): Binary search for insertion positionsgenerateJacobsthalSequenceVector(): Generates Jacobsthal numbers
mergeInsertSortDeque(): Main sorting logic for dequeperformInsertionSortDeque(): Insertion phase for dequebinarySearchPositionDeque(): Binary search for dequegenerateJacobsthalSequenceDeque(): Jacobsthal sequence for deque
The insertion order follows Jacobsthal numbers:
J(0) = 0
J(1) = 1
J(n) = J(n-1) + 2Β·J(n-2)
Sequence: 1, 3, 5, 11, 21, 43, 85, 171, 341...
This ordering minimizes the maximum number of comparisons needed for insertions.
# Should always return exactly 66 comparisons
for i in {1..10}; do
echo "Test $i:"
./FordJohnson `shuf -i 1-100000 -n 21 | tr "\n" " "` | grep comparisons
done# Test with 3000 elements
./FordJohnson `shuf -i 1-100000 -n 3000 | tr "\n" " "`# Single element
./FordJohnson 42
# Two elements
./FordJohnson 10 5
# Already sorted
./FordJohnson 1 2 3 4 5 6 7 8 9 10
# Reverse sorted
./FordJohnson 10 9 8 7 6 5 4 3 2 1# Maximum range test
./FordJohnson `shuf -i 1-1000000 -n 5000 | tr "\n" " "`The program includes built-in validation:
- β Checks for non-numeric input
- β Detects duplicate values
- β Validates integer overflow
- β Ensures at least one input is provided
| Metric | Complexity |
|---|---|
| Time (Best) | O(n log n) |
| Time (Average) | O(n log n) |
| Time (Worst) | O(n log n) |
| Space | O(n) |
| Comparisons | Optimal for small n |
| Algorithm | Comparisons (n=21) | Time Complexity | Space Complexity |
|---|---|---|---|
| Ford-Johnson | 66 β | O(n log n) | O(n) |
| Merge Sort | ~70-75 | O(n log n) | O(n) |
| Quick Sort | ~65-80 | O(n log n) avg | O(log n) |
| Heap Sort | ~75-85 | O(n log n) | O(1) |
| Insertion Sort | ~110-210 | O(nΒ²) | O(1) |
- Language: C++98
- Compiler Flags:
-Wall -Wextra -Werror -std=c++98 - Containers:
std::vector,std::deque - No External Libraries: Only standard C++ library
- Educational Value: Demonstrates advanced algorithmic concepts
- Historical Significance: One of the earliest optimal sorting algorithms
- Comparison Optimality: Achieves minimum comparisons for many input sizes
- Practical Insights: Shows the importance of insertion order and binary search
- Ford, L. R., & Johnson, S. M. (1959). A Tournament Problem. The American Mathematical Monthly, 66(5), 387-389.
- Knuth, D. E. (1998). The Art of Computer Programming, Volume 3: Sorting and Searching (2nd ed.).
- Jacobsthal Numbers - The On-Line Encyclopedia of Integer Sequences
ITAXBOX
- GitHub: @ITAXBOX
- Project: Ford-Johnson-Algorithm
This project is available for educational purposes. Feel free to use and modify for learning.
β If you found this implementation helpful, please consider giving it a star! β
Made with precision and attention to algorithmic detail
