evillatoro_data_structures/
linked_list.rs1use std::fmt::Display;
2
3pub struct ListNode<T: Display> {
4 pub data: T,
5 pub next: Option<Box<ListNode<T>>>,
6}
7
8impl<T: Display> ListNode<T> {
9 pub fn new(value: T) -> ListNode<T> {
10 ListNode {
11 data: value,
12 next: None,
13 }
14 }
15
16 fn _to_string_debug(&self) -> String {
17 format!("[{:p}]", self)
18 }
19
20 fn to_string(&self) -> String {
21 format!("[{}]", self.data)
22 }
23}
24
25pub fn print<T: Display>(head: &ListNode<T>) {
26 let mut cur = Some(head);
27
28 while let Some(node) = cur {
29 print!("{} -> ", node.to_string());
30 cur = node.next.as_deref();
31 }
32 println!("None");
33}
34
35pub fn print_summary<T: Display>(head: &ListNode<T>) {
36 print(&head);
37 println!("Linked list length {len}", len = length(&head));
38}
39
40pub fn length<T: Display>(head: &ListNode<T>) -> i32 {
41 let mut cur = Some(head);
42 let mut count = 0;
43 while let Some(node) = cur {
44 count += 1;
45 cur = node.next.as_deref();
46 }
47 count
48}
49
50pub fn insert_at_beginning<T: Display>(
52 head: Option<Box<ListNode<T>>>,
53 data: T,
54) -> Box<ListNode<T>> {
55 let mut new_node = Box::new(ListNode::new(data));
56
57 match head {
58 Some(node) => {
59 new_node.next = Some(node);
60 return new_node;
61 }
62 None => new_node,
63 }
64}
65
66pub fn insert_at_end<T: Display>(mut head: Option<Box<ListNode<T>>>, data: T) -> Box<ListNode<T>> {
67 let new_node = Box::new(ListNode::new(data));
68
69 match head {
70 Some(ref mut node) => {
71 let mut cur = node;
72 while let Some(ref mut temp) = cur.next {
73 cur = temp;
74 }
75 cur.next = Some(new_node);
76 return head.unwrap();
77 }
78 None => new_node,
79 }
80}
81
82pub fn insert_at_position<T: Display>(
83 mut head: Option<Box<ListNode<T>>>,
84 data: T,
85 pos: usize,
86) -> Box<ListNode<T>> {
87 if pos == 0 {
88 return insert_at_beginning(head, data);
89 }
90
91 let mut cur = &mut head;
92 let mut counter = 0;
93
94 while let Some(ref mut node) = *cur {
95 if counter == pos - 1 {
96 let mut new_node = ListNode::new(data);
97 new_node.next = node.next.take();
98 node.next = Some(Box::new(new_node));
99
100 return head.expect("head node must exist to insert at position");
101 }
102
103 counter += 1;
104 cur = &mut (*node).next;
105 }
106
107 return head.expect("head node must exist to insert at position");
108}
109
110pub fn delete_first<T: Display>(head: Option<Box<ListNode<T>>>) -> Option<Box<ListNode<T>>> {
112 match head {
113 Some(first_node) => return first_node.next,
114 None => None,
115 }
116}
117
118pub fn delete_last<T: Display>(mut head: Option<Box<ListNode<T>>>) -> Option<Box<ListNode<T>>> {
119 match head {
120 Some(ref mut node) => {
121 let mut cur = node;
122
123 while let Some(ref mut current) = (*cur).next {
125 let next = ¤t.next;
126 if let Some(next) = next {
131 if next.next.is_none() {
132 (*current).next = None;
133 return head;
134 }
135 }
136 cur = current;
137 }
138 return None;
140 }
141 None => None,
142 }
143}
144
145pub fn delete_at_position<T: Display>(
146 mut head: Option<Box<ListNode<T>>>,
147 position: usize,
148) -> Option<Box<ListNode<T>>> {
149 if position == 0 {
150 return delete_first(head);
151 }
152
153 match head {
154 Some(ref mut node) => {
155 let mut cur = node;
156 let mut counter = 1;
157
158 while let Some(ref mut current) = (*cur).next {
160 if counter == position - 1 {
167 if let Some(ref mut next) = current.next {
168 (*current).next = (*next).next.take();
169 }
170 return head;
171 }
172 if counter >= position - 1 {
173 break;
174 }
175 cur = current;
176 counter += 1;
177 }
178
179 return head;
180 }
181 None => None,
182 }
183}
184
185#[cfg(test)]
186mod tests {
187 use super::*;
188 #[test]
189 fn test_linked_list_to_string() {
190 println!("Test");
191 let head = insert_at_beginning::<i32>(None, 1);
192 let string = head.to_string();
193 assert!(!string.is_empty());
194 assert_eq!(string, "[1]");
195 assert_ne!(string, "[2]");
196 }
197
198 #[test]
199 fn test_print() {
200 let head = insert_at_beginning::<i32>(None, 1);
201 print(&head);
202 print_summary(&head);
203 }
204
205 #[test]
206 fn test_length() {
207 let mut head = insert_at_beginning::<i32>(None, 1);
208 head = insert_at_beginning(Some(head), 1);
209 head = insert_at_beginning(Some(head), 1);
210
211 assert_eq!(length(&head), 3);
212 }
213
214 #[test]
215 fn test_linked_list_to_string_debug() {
216 let head = insert_at_beginning::<i32>(None, 1);
217 let string = head._to_string_debug();
218 assert!(!string.is_empty());
219 assert_ne!(string, "[2]");
220 }
221
222 #[test]
223 fn test_insert_at_beggining() {
224 let head = insert_at_beginning::<i32>(None, 1);
225 assert_eq!((*head).data, 1);
226 assert!((*head).next.is_none());
227 }
228
229 #[test]
230 fn test_insert_at_incorrect() {
231 let head = insert_at_beginning::<i32>(None, 1);
232 assert_ne!((*head).data, 10);
233 assert!(!(*head).next.is_some());
234 }
235
236 #[test]
237 fn test_insert_at_beggining_existing_list() {
238 let mut head = insert_at_beginning::<i32>(None, 2);
239 head = insert_at_beginning(Some(head), 1);
240 assert_eq!((*head).data, 1);
242 assert!((*head).next.is_some());
244 let next_node = head.next.unwrap();
246 assert_eq!(next_node.data, 2);
247 assert!(next_node.next.is_none());
249 }
250
251 #[test]
252 fn test_insert_at_end() {
253 let mut head = insert_at_end::<i32>(None, 1);
254 assert_eq!((*head).data, 1);
255 assert!((*head).next.is_none());
256 head = insert_at_end(Some(head), 3);
257 head = insert_at_end(Some(head), 2);
258 assert_eq!((*head).data, 1);
259 assert!((*head).next.is_some());
260 }
261
262 #[test]
263 fn test_insert_at_position() {
264 let mut head = insert_at_position::<i32>(None, 1, 0);
265 assert_eq!((*head).data, 1);
266 assert!((*head).next.is_none());
267
268 let list_length = 29;
269
270 for i in 0..list_length - 2 {
271 head = insert_at_position(Some(head), i, 0);
272 }
273
274 let position = 15;
275 let value = 69;
276 head = insert_at_position(Some(head), 69, position);
277
278 let mut counter = 0;
279 let mut cur = &head;
280
281 while counter < position {
282 if let Some(ref node) = cur.next {
283 cur = &node;
284 counter += 1;
285 }
286 }
287 print_summary(&head);
288 assert_eq!(length(&head), list_length);
289 assert_eq!((*cur).data, value);
290 }
291
292 #[test]
293 #[should_panic]
294 fn test_insert_at_wrong_position() {
295 insert_at_position::<i32>(None, 1, 10);
296 }
297
298 #[test]
299 fn test_delete_first() {
300 let none = delete_first::<i32>(None);
301
302 assert!(none.is_none());
303
304 let mut head = insert_at_beginning::<i32>(None, 4);
305 head = insert_at_beginning(Some(head), 3);
307 head = insert_at_beginning(Some(head), 2);
308 head = insert_at_beginning(Some(head), 1);
309
310 let new_head = delete_first::<i32>(Some(head));
311
312 assert!(new_head.is_some());
313
314 match new_head {
315 Some(node) => {
316 assert_eq!(2, node.data)
317 }
318 None => panic!("The new head should exist"),
319 }
320 }
321
322 #[test]
323 fn test_delete_last() {
324 let none = delete_last::<i32>(None);
325
326 assert!(none.is_none());
327
328 let mut list_length = 100;
329
330 let mut head = insert_at_beginning::<i32>(None, 69);
331
332 for i in 1..list_length {
333 head = insert_at_beginning(Some(head), i);
334 }
335 print_summary(&head);
336
337 head = delete_last(Some(head)).unwrap();
338 list_length -= 1;
339
340 let mut cur = &head;
341
342 while let Some(ref node) = (*cur).next {
343 cur = node;
344 }
345
346 assert_eq!(list_length, length(&head));
347 assert_eq!(1, (*cur).data);
348 }
349
350 #[test]
351 fn test_delete_last_single_node() {
352 let mut head = Some(insert_at_beginning::<i32>(None, 69));
353
354 head = delete_last(head);
355
356 assert!(head.is_none());
357 }
358
359 #[test]
360 fn test_delete_at_position() {
361 let list_length = 5;
362 let mut head = insert_at_beginning(None, list_length);
363
364 for i in 1..list_length {
365 head = insert_at_beginning(Some(head), list_length - i);
366 }
367
368 let delete_position = 2;
369 let mut counter = 0;
370
371 let original_data: i32;
372
373 {
374 let mut original_cur = &head;
375 while counter < delete_position {
376 if let Some(ref node) = original_cur.next {
377 original_cur = &node;
378 counter += 1;
379 }
380 }
381 original_data = (*original_cur).data;
382 }
383
384 head = delete_at_position(Some(head), delete_position).unwrap();
385
386 let mut counter = 0;
387 let mut cur = &head;
388
389 while counter < delete_position {
390 if let Some(ref node) = cur.next {
391 cur = &node;
392 counter += 1;
393 }
394 }
395 assert_ne!(original_data, (*cur).data);
396 }
397
398 #[test]
399 fn delete_at_position_fist_item() {
400 let mut head = insert_at_beginning(None, 1);
401 head = insert_at_beginning(Some(head), 0);
402
403 head = delete_at_position(Some(head), 0).unwrap();
404
405 assert_eq!(1, head.data);
406 }
407
408 #[test]
409 fn delete_at_position_out_of_bounds() {
410 let list_length = 5;
411 let mut head = insert_at_beginning::<i32>(None, list_length);
412
413 for i in 1..list_length {
414 head = insert_at_beginning(Some(head), list_length - i);
415 }
416
417 head = delete_at_position(Some(head), (list_length + 1000) as usize).unwrap();
418
419 assert_eq!(length(&head), list_length);
421 }
422
423 #[test]
424 fn delete_at_position_none_head() {
425 assert!(delete_at_position::<i32>(None, 100).is_none())
426 }
427}