|
| 1 | +# Linked List Algorithms |
| 2 | + |
| 3 | +This directory contains comprehensive implementations of various linked list data structures in R. Linked lists are fundamental linear data structures where elements are stored in nodes, and each node contains data and reference(s) to other nodes. |
| 4 | + |
| 5 | +## 📋 Contents |
| 6 | + |
| 7 | +- [`singly_linked_list.r`](singly_linked_list.r) - Singly Linked List implementation |
| 8 | +- [`doubly_linked_list.r`](doubly_linked_list.r) - Doubly Linked List implementation |
| 9 | +- [`circular_linked_list.r`](circular_linked_list.r) - Circular Linked List implementation |
| 10 | +- [`README.md`](README.md) - This documentation file |
| 11 | + |
| 12 | +## 🔗 Linked List Types Overview |
| 13 | + |
| 14 | +### 1. Singly Linked List |
| 15 | +**Structure**: Each node contains data and a pointer to the next node |
| 16 | +**Traversal**: Forward only (head → tail) |
| 17 | +**Memory**: Minimal overhead (one pointer per node) |
| 18 | + |
| 19 | +**Use Cases**: |
| 20 | +- Implementing stacks and queues |
| 21 | +- Undo functionality in applications |
| 22 | +- Simple sequential data storage |
| 23 | + |
| 24 | +### 2. Doubly Linked List |
| 25 | +**Structure**: Each node contains data and pointers to both next and previous nodes |
| 26 | +**Traversal**: Bidirectional (forward and backward) |
| 27 | +**Memory**: Higher overhead (two pointers per node) |
| 28 | + |
| 29 | +**Use Cases**: |
| 30 | +- Browser history navigation (back/forward) |
| 31 | +- LRU cache implementation |
| 32 | +- Complex navigation systems |
| 33 | + |
| 34 | +### 3. Circular Linked List |
| 35 | +**Structure**: Last node points back to the first node (forms a circle) |
| 36 | +**Traversal**: Infinite circular traversal possible |
| 37 | +**Memory**: Same as singly linked (one pointer per node) |
| 38 | + |
| 39 | +**Use Cases**: |
| 40 | +- Round-robin CPU scheduling |
| 41 | +- Multiplayer turn-based games |
| 42 | +- Continuous playlists |
| 43 | + |
| 44 | +## ⚡ Performance Comparison |
| 45 | + |
| 46 | +| Operation | Singly | Doubly | Circular | |
| 47 | +|-----------|--------|--------|----------| |
| 48 | +| Insert at Head | O(1) | O(1) | O(1) | |
| 49 | +| Insert at Tail | O(n) | O(1) | O(n) | |
| 50 | +| Delete from Head | O(1) | O(1) | O(1) | |
| 51 | +| Delete from Tail | O(n) | O(1) | O(n) | |
| 52 | +| Search | O(n) | O(n) | O(n) | |
| 53 | +| Access by Index | O(n) | O(n/2)* | O(n) | |
| 54 | + |
| 55 | +*Doubly linked list can traverse from closer end (head or tail) |
| 56 | + |
| 57 | +## 🚀 Quick Start Guide |
| 58 | + |
| 59 | +### Installation |
| 60 | +No additional packages required! Just R base installation with `setRefClass` support. |
| 61 | + |
| 62 | +### Basic Usage Examples |
| 63 | + |
| 64 | +#### Singly Linked List |
| 65 | +```r |
| 66 | +source("singly_linked_list.r") |
| 67 | + |
| 68 | +# Create new list |
| 69 | +my_list <- SinglyLinkedList$new() |
| 70 | + |
| 71 | +# Basic operations |
| 72 | +my_list$insert_at_head(10) |
| 73 | +my_list$insert_at_tail(20) |
| 74 | +my_list$insert_at_position(15, 1) |
| 75 | +my_list$print_list() |
| 76 | + |
| 77 | +# Access and search |
| 78 | +value <- my_list$get(1) # Get element at position 1 |
| 79 | +position <- my_list$search(15) # Find position of value 15 |
| 80 | +vector_form <- my_list$to_vector() # Convert to R vector |
| 81 | + |
| 82 | +# Delete operations |
| 83 | +my_list$delete_from_head() |
| 84 | +my_list$delete_by_value(15) |
| 85 | +``` |
| 86 | + |
| 87 | +#### Doubly Linked List |
| 88 | +```r |
| 89 | +source("doubly_linked_list.r") |
| 90 | + |
| 91 | +# Create new doubly linked list |
| 92 | +dll <- DoublyLinkedList$new() |
| 93 | + |
| 94 | +# Bidirectional operations |
| 95 | +dll$insert_at_head(10) |
| 96 | +dll$insert_at_tail(20) |
| 97 | +dll$print_list() # Forward traversal |
| 98 | +dll$print_list_reverse() # Backward traversal |
| 99 | + |
| 100 | +# Optimized access (traverses from closer end) |
| 101 | +dll$get(0) # Accessed from head |
| 102 | +dll$get(dll$get_size() - 1) # Accessed from tail |
| 103 | + |
| 104 | +# Convert to vectors |
| 105 | +forward_vector <- dll$to_vector() |
| 106 | +backward_vector <- dll$to_vector_reverse() |
| 107 | +``` |
| 108 | + |
| 109 | +#### Circular Linked List |
| 110 | +```r |
| 111 | +source("circular_linked_list.r") |
| 112 | + |
| 113 | +# Create new circular linked list |
| 114 | +cll <- CircularLinkedList$new() |
| 115 | + |
| 116 | +# Build the circle |
| 117 | +cll$insert_at_tail(1) |
| 118 | +cll$insert_at_tail(2) |
| 119 | +cll$insert_at_tail(3) |
| 120 | + |
| 121 | +# Demonstrate circular nature |
| 122 | +cll$traverse_n_times(2) # Go around circle twice |
| 123 | + |
| 124 | +# Solve classic problems |
| 125 | +survivor <- cll$josephus_problem(3) # Josephus problem with k=3 |
| 126 | +``` |
| 127 | + |
| 128 | +## 🎯 Advanced Features |
| 129 | + |
| 130 | +### Comprehensive Operations |
| 131 | +All implementations include: |
| 132 | +- **Insertion**: at head, tail, or any position |
| 133 | +- **Deletion**: from head, tail, position, or by value |
| 134 | +- **Search**: find element position |
| 135 | +- **Access**: get element by position |
| 136 | +- **Utilities**: size, empty check, clear, convert to vector |
| 137 | + |
| 138 | +### Algorithm Implementations |
| 139 | +- **Middle element detection** (two-pointer technique) |
| 140 | +- **Cycle detection** (Floyd's algorithm) |
| 141 | +- **List reversal** (in-place) |
| 142 | +- **Josephus problem** (circular list specialty) |
| 143 | + |
| 144 | +### Educational Features |
| 145 | +- **Step-by-step explanations** with console output |
| 146 | +- **Time/space complexity analysis** in comments |
| 147 | +- **Real-world examples** and use cases |
| 148 | +- **Interactive demonstrations** for each type |
| 149 | + |
| 150 | +## 🔬 Detailed Examples |
| 151 | + |
| 152 | +### Running the Demonstrations |
| 153 | +Each implementation includes comprehensive examples: |
| 154 | + |
| 155 | +```r |
| 156 | +# Singly Linked List examples |
| 157 | +source("singly_linked_list.r") |
| 158 | +demonstrate_singly_linked_list() |
| 159 | + |
| 160 | +# Doubly Linked List examples |
| 161 | +source("doubly_linked_list.r") |
| 162 | +demonstrate_doubly_linked_list() |
| 163 | + |
| 164 | +# Circular Linked List examples |
| 165 | +source("circular_linked_list.r") |
| 166 | +demonstrate_circular_linked_list() |
| 167 | +``` |
| 168 | + |
| 169 | +### Real-World Applications |
| 170 | + |
| 171 | +#### 1. Student Grade Management (Singly Linked List) |
| 172 | +```r |
| 173 | +grades_list <- SinglyLinkedList$new() |
| 174 | +grades <- c(85, 92, 78, 96, 83, 89) |
| 175 | + |
| 176 | +# Add grades |
| 177 | +for (grade in grades) { |
| 178 | + grades_list$insert_at_tail(grade) |
| 179 | +} |
| 180 | + |
| 181 | +# Calculate statistics |
| 182 | +grade_vector <- grades_list$to_vector() |
| 183 | +average <- mean(grade_vector) |
| 184 | +``` |
| 185 | + |
| 186 | +#### 2. Browser History (Doubly Linked List) |
| 187 | +```r |
| 188 | +history <- DoublyLinkedList$new() |
| 189 | + |
| 190 | +# Visit pages |
| 191 | +history$insert_at_tail("google.com") |
| 192 | +history$insert_at_tail("github.com") |
| 193 | +history$insert_at_tail("stackoverflow.com") |
| 194 | + |
| 195 | +# Go back (delete current) |
| 196 | +current_page <- history$delete_from_tail() |
| 197 | + |
| 198 | +# Go forward (add new page) |
| 199 | +history$insert_at_tail("wikipedia.org") |
| 200 | +``` |
| 201 | + |
| 202 | +#### 3. Round-Robin Scheduling (Circular Linked List) |
| 203 | +```r |
| 204 | +scheduler <- CircularLinkedList$new() |
| 205 | + |
| 206 | +# Add processes |
| 207 | +processes <- c("Process_A", "Process_B", "Process_C") |
| 208 | +for (process in processes) { |
| 209 | + scheduler$insert_at_tail(process) |
| 210 | +} |
| 211 | + |
| 212 | +# Simulate time slots |
| 213 | +current <- scheduler$head |
| 214 | +for (slot in 1:6) { |
| 215 | + cat("Time slot", slot, ":", current$data, "\n") |
| 216 | + current <- current$next_node |
| 217 | +} |
| 218 | +``` |
| 219 | + |
| 220 | +## 🧮 Algorithm Analysis |
| 221 | + |
| 222 | +### Space Complexity |
| 223 | +- **Singly**: O(n) space, 1 pointer per node |
| 224 | +- **Doubly**: O(n) space, 2 pointers per node |
| 225 | +- **Circular**: O(n) space, 1 pointer per node |
| 226 | + |
| 227 | +### When to Use Each Type |
| 228 | + |
| 229 | +| Requirement | Best Choice | Reason | |
| 230 | +|-------------|-------------|---------| |
| 231 | +| Memory efficiency | Singly | Minimal pointer overhead | |
| 232 | +| Bidirectional traversal | Doubly | Two-way navigation | |
| 233 | +| Cyclic operations | Circular | Natural circular structure | |
| 234 | +| Frequent tail operations | Doubly | O(1) tail access | |
| 235 | +| Simple implementation | Singly | Easiest to understand/debug | |
| 236 | +| LRU Cache | Doubly | Efficient insertion/deletion anywhere | |
| 237 | +| Round-robin algorithms | Circular | Natural fit for cyclic scheduling | |
| 238 | + |
| 239 | +## ⚠️ Important Considerations |
| 240 | + |
| 241 | +### Common Pitfalls |
| 242 | +1. **Memory Leaks**: Ensure proper node cleanup in languages with manual memory management |
| 243 | +2. **Infinite Loops**: In circular lists, always track traversal completion |
| 244 | +3. **Null Pointer Exceptions**: Check for empty lists before operations |
| 245 | +4. **Position Bounds**: Validate position parameters in insert/delete operations |
| 246 | + |
| 247 | +### Best Practices |
| 248 | +1. **Always validate inputs** (positions, null checks) |
| 249 | +2. **Maintain size counter** for O(1) size queries |
| 250 | +3. **Use appropriate type** based on access patterns |
| 251 | +4. **Test edge cases** (empty list, single element, position bounds) |
| 252 | +5. **Document time complexities** for each operation |
| 253 | + |
| 254 | +## 📚 Further Reading |
| 255 | + |
| 256 | +### Recommended Algorithms to Implement Next |
| 257 | +- **Stack using Linked List**: LIFO operations |
| 258 | +- **Queue using Linked List**: FIFO operations |
| 259 | +- **Deque using Doubly Linked List**: Double-ended queue |
| 260 | +- **LRU Cache using Doubly Linked List**: Cache replacement policy |
| 261 | +- **Skip List**: Probabilistic data structure for fast search |
| 262 | + |
| 263 | +### Advanced Topics |
| 264 | +- **Lock-free Linked Lists**: Concurrent programming |
| 265 | +- **Memory Pool Allocation**: Efficient node management |
| 266 | +- **Template/Generic Implementations**: Type-safe containers |
| 267 | +- **Persistent Linked Lists**: Functional programming approach |
| 268 | + |
| 269 | +## 🤝 Contributing |
| 270 | + |
| 271 | +We welcome contributions! Consider adding: |
| 272 | +- Additional linked list variants (XOR linked list, skip list) |
| 273 | +- Performance benchmarking utilities |
| 274 | +- Visualization functions (ASCII art display) |
| 275 | +- More real-world application examples |
| 276 | +- Memory usage analysis tools |
| 277 | + |
| 278 | +### Development Guidelines |
| 279 | +1. Follow existing code style and documentation standards |
| 280 | +2. Include comprehensive test cases and examples |
| 281 | +3. Add time/space complexity analysis in comments |
| 282 | +4. Provide practical application demonstrations |
| 283 | +5. Ensure no automatic side effects (examples available but not auto-run) |
| 284 | + |
| 285 | +## 📄 License |
| 286 | + |
| 287 | +This code is provided for educational purposes. Please cite appropriately if used in academic work. |
| 288 | + |
| 289 | +--- |
| 290 | + |
| 291 | +*"A linked list is a linear collection of data elements whose order is not given by their physical placement in memory."* |
| 292 | + |
| 293 | +These implementations provide a solid foundation for understanding linked lists and can serve as building blocks for more complex data structures and algorithms! |
0 commit comments