1use std::fmt::{self, Display, Formatter};
2use std::marker::PhantomData;
3use std::ptr::NonNull;
4
5struct Node<T> {
6 val: T,
7 next: Option<NonNull<Node<T>>>,
8 prev: Option<NonNull<Node<T>>>,
9}
10
11impl<T> Node<T> {
12 fn new(t: T) -> Node<T> {
13 Node {
14 val: t,
15 prev: None,
16 next: None,
17 }
18 }
19}
20
21pub struct LinkedList<T> {
22 length: u32,
23 head: Option<NonNull<Node<T>>>,
24 tail: Option<NonNull<Node<T>>>,
25 marker: PhantomData<Box<Node<T>>>,
27}
28
29impl<T> Default for LinkedList<T> {
30 fn default() -> Self {
31 Self::new()
32 }
33}
34
35impl<T> LinkedList<T> {
36 pub fn new() -> Self {
37 Self {
38 length: 0,
39 head: None,
40 tail: None,
41 marker: PhantomData,
42 }
43 }
44
45 pub fn insert_at_head(&mut self, obj: T) {
46 let mut node = Box::new(Node::new(obj));
47 node.next = self.head;
48 node.prev = None;
49 let node_ptr = Some(unsafe { NonNull::new_unchecked(Box::into_raw(node)) });
50 match self.head {
51 None => self.tail = node_ptr,
52 Some(head_ptr) => unsafe { (*head_ptr.as_ptr()).prev = node_ptr },
53 }
54 self.head = node_ptr;
55 self.length += 1;
56 }
57
58 pub fn insert_at_tail(&mut self, obj: T) {
59 let mut node = Box::new(Node::new(obj));
60 node.next = None;
61 node.prev = self.tail;
62 let node_ptr = Some(unsafe { NonNull::new_unchecked(Box::into_raw(node)) });
63 match self.tail {
64 None => self.head = node_ptr,
65 Some(tail_ptr) => unsafe { (*tail_ptr.as_ptr()).next = node_ptr },
66 }
67 self.tail = node_ptr;
68 self.length += 1;
69 }
70
71 pub fn insert_at_ith(&mut self, index: u32, obj: T) {
72 if self.length < index {
73 panic!("Index out of bounds");
74 }
75
76 if index == 0 || self.head == None {
77 self.insert_at_head(obj);
78 return;
79 }
80
81 if self.length == index {
82 self.insert_at_tail(obj);
83 return;
84 }
85
86 if let Some(mut ith_node) = self.head {
87 for _ in 0..index {
88 unsafe {
89 match (*ith_node.as_ptr()).next {
90 None => panic!("Index out of bounds"),
91 Some(next_ptr) => ith_node = next_ptr,
92 }
93 }
94 }
95
96 let mut node = Box::new(Node::new(obj));
97 unsafe {
98 node.prev = (*ith_node.as_ptr()).prev;
99 node.next = Some(ith_node);
100 if let Some(p) = (*ith_node.as_ptr()).prev {
101 let node_ptr = Some(NonNull::new_unchecked(Box::into_raw(node)));
102 println!("{:?}", (*p.as_ptr()).next);
103 (*p.as_ptr()).next = node_ptr;
104 self.length += 1;
105 }
106 }
107 }
108 }
109
110 pub fn delete_head(&mut self) -> Option<T> {
111 self.head.map(|head_ptr| unsafe {
114 let old_head = Box::from_raw(head_ptr.as_ptr());
115 match old_head.next {
116 Some(mut next_ptr) => next_ptr.as_mut().prev = None,
117 None => self.tail = None,
118 }
119 self.head = old_head.next;
120 self.length -= 1;
121 old_head.val
122 })
123 }
124
125 pub fn delete_tail(&mut self) -> Option<T> {
126 self.tail.map(|tail_ptr| unsafe {
129 let old_tail = Box::from_raw(tail_ptr.as_ptr());
130 match old_tail.prev {
131 Some(mut prev) => prev.as_mut().next = None,
132 None => self.head = None,
133 }
134 self.tail = old_tail.prev;
135 self.length -= 1;
136 old_tail.val
137 })
138 }
139
140 pub fn delete_ith(&mut self, index: u32) -> Option<T> {
141 if self.length < index {
142 panic!("Index out of bounds");
143 }
144
145 if index == 0 || self.head == None {
146 return self.delete_head();
147 }
148
149 if self.length == index {
150 return self.delete_tail();
151 }
152
153 if let Some(mut ith_node) = self.head {
154 for _ in 0..index {
155 unsafe {
156 match (*ith_node.as_ptr()).next {
157 None => panic!("Index out of bounds"),
158 Some(next_ptr) => ith_node = next_ptr,
159 }
160 }
161 }
162
163 unsafe {
164 let old_ith = Box::from_raw(ith_node.as_ptr());
165 if let Some(mut prev) = old_ith.prev {
166 prev.as_mut().next = old_ith.next;
167 }
168 if let Some(mut next) = old_ith.next {
169 next.as_mut().prev = old_ith.prev;
170 }
171
172 self.length -= 1;
173 Some(old_ith.val)
174 }
175 } else {
176 None
177 }
178 }
179
180 pub fn get(&mut self, index: i32) -> Option<&T> {
181 self.get_ith_node(self.head, index)
182 }
183
184 fn get_ith_node(&mut self, node: Option<NonNull<Node<T>>>, index: i32) -> Option<&T> {
185 match node {
186 None => None,
187 Some(next_ptr) => match index {
188 0 => Some(unsafe { &(*next_ptr.as_ptr()).val }),
189 _ => self.get_ith_node(unsafe { (*next_ptr.as_ptr()).next }, index - 1),
190 },
191 }
192 }
193}
194
195impl<T> Drop for LinkedList<T> {
196 fn drop(&mut self) {
197 while self.delete_head().is_some() {}
199 }
200}
201
202impl<T> Display for LinkedList<T>
203where
204 T: Display,
205{
206 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
207 match self.head {
208 Some(node) => write!(f, "{}", unsafe { node.as_ref() }),
209 None => Ok(()),
210 }
211 }
212}
213
214impl<T> Display for Node<T>
215where
216 T: Display,
217{
218 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
219 match self.next {
220 Some(node) => write!(f, "{}, {}", self.val, unsafe { node.as_ref() }),
221 None => write!(f, "{}", self.val),
222 }
223 }
224}
225
226#[cfg(test)]
227mod tests {
228 use std::convert::TryInto;
229
230 use super::LinkedList;
231
232 #[test]
233 fn insert_at_tail_works() {
234 let mut list = LinkedList::<i32>::new();
235 let second_value = 2;
236 list.insert_at_tail(1);
237 list.insert_at_tail(second_value);
238 println!("Linked List is {}", list);
239 match list.get(1) {
240 Some(val) => assert_eq!(*val, second_value),
241 None => panic!("Expected to find {} at index 1", second_value),
242 }
243 }
244 #[test]
245 fn insert_at_head_works() {
246 let mut list = LinkedList::<i32>::new();
247 let second_value = 2;
248 list.insert_at_head(1);
249 list.insert_at_head(second_value);
250 println!("Linked List is {}", list);
251 match list.get(0) {
252 Some(val) => assert_eq!(*val, second_value),
253 None => panic!("Expected to find {} at index 0", second_value),
254 }
255 }
256
257 #[test]
258 fn insert_at_ith_can_add_to_tail() {
259 let mut list = LinkedList::<i32>::new();
260 let second_value = 2;
261 list.insert_at_ith(0, 0);
262 list.insert_at_ith(1, second_value);
263 println!("Linked List is {}", list);
264 match list.get(1) {
265 Some(val) => assert_eq!(*val, second_value),
266 None => panic!("Expected to find {} at index 1", second_value),
267 }
268 }
269
270 #[test]
271 fn insert_at_ith_can_add_to_head() {
272 let mut list = LinkedList::<i32>::new();
273 let second_value = 2;
274 list.insert_at_ith(0, 1);
275 list.insert_at_ith(0, second_value);
276 println!("Linked List is {}", list);
277 match list.get(0) {
278 Some(val) => assert_eq!(*val, second_value),
279 None => panic!("Expected to find {} at index 0", second_value),
280 }
281 }
282
283 #[test]
284 fn insert_at_ith_can_add_to_middle() {
285 let mut list = LinkedList::<i32>::new();
286 let second_value = 2;
287 let third_value = 3;
288 list.insert_at_ith(0, 1);
289 list.insert_at_ith(1, second_value);
290 list.insert_at_ith(1, third_value);
291 println!("Linked List is {}", list);
292 match list.get(1) {
293 Some(val) => assert_eq!(*val, third_value),
294 None => panic!("Expected to find {} at index 1", third_value),
295 }
296
297 match list.get(2) {
298 Some(val) => assert_eq!(*val, second_value),
299 None => panic!("Expected to find {} at index 1", second_value),
300 }
301 }
302
303 #[test]
304 fn insert_at_ith_and_delete_ith_work_over_many_iterations() {
305 let mut list = LinkedList::<i32>::new();
306 for i in 0..100 {
307 list.insert_at_ith(i, i.try_into().unwrap());
308 }
309
310 for i in 0..50 {
312 println!("list.length {}", list.length);
313 if i % 2 == 0 {
314 list.delete_ith(i);
315 }
316 }
317
318 assert_eq!(list.length, 75);
319
320 for i in 0..50 {
322 if i % 2 == 0 {
323 list.insert_at_ith(i, i.try_into().unwrap());
324 }
325 }
326
327 assert_eq!(list.length, 100);
328
329 if let Some(val) = list.get(78) {
331 assert_eq!(*val, 78);
332 } else {
333 panic!("Expected to find 78 at index 78");
334 }
335 }
336
337 #[test]
338 fn delete_tail_works() {
339 let mut list = LinkedList::<i32>::new();
340 let first_value = 1;
341 let second_value = 2;
342 list.insert_at_tail(first_value);
343 list.insert_at_tail(second_value);
344 match list.delete_tail() {
345 Some(val) => assert_eq!(val, 2),
346 None => panic!("Expected to remove {} at tail", second_value),
347 }
348
349 println!("Linked List is {}", list);
350 match list.get(0) {
351 Some(val) => assert_eq!(*val, first_value),
352 None => panic!("Expected to find {} at index 0", first_value),
353 }
354 }
355
356 #[test]
357 fn delete_head_works() {
358 let mut list = LinkedList::<i32>::new();
359 let first_value = 1;
360 let second_value = 2;
361 list.insert_at_tail(first_value);
362 list.insert_at_tail(second_value);
363 match list.delete_head() {
364 Some(val) => assert_eq!(val, 1),
365 None => panic!("Expected to remove {} at head", first_value),
366 }
367
368 println!("Linked List is {}", list);
369 match list.get(0) {
370 Some(val) => assert_eq!(*val, second_value),
371 None => panic!("Expected to find {} at index 0", second_value),
372 }
373 }
374
375 #[test]
376 fn delete_ith_can_delete_at_tail() {
377 let mut list = LinkedList::<i32>::new();
378 let first_value = 1;
379 let second_value = 2;
380 list.insert_at_tail(first_value);
381 list.insert_at_tail(second_value);
382 match list.delete_ith(1) {
383 Some(val) => assert_eq!(val, 2),
384 None => panic!("Expected to remove {} at tail", second_value),
385 }
386
387 assert_eq!(list.length, 1);
388 }
389
390 #[test]
391 fn delete_ith_can_delete_at_head() {
392 let mut list = LinkedList::<i32>::new();
393 let first_value = 1;
394 let second_value = 2;
395 list.insert_at_tail(first_value);
396 list.insert_at_tail(second_value);
397 match list.delete_ith(0) {
398 Some(val) => assert_eq!(val, 1),
399 None => panic!("Expected to remove {} at tail", first_value),
400 }
401
402 assert_eq!(list.length, 1);
403 }
404
405 #[test]
406 fn delete_ith_can_delete_in_middle() {
407 let mut list = LinkedList::<i32>::new();
408 let first_value = 1;
409 let second_value = 2;
410 let third_value = 3;
411 list.insert_at_tail(first_value);
412 list.insert_at_tail(second_value);
413 list.insert_at_tail(third_value);
414 match list.delete_ith(1) {
415 Some(val) => assert_eq!(val, 2),
416 None => panic!("Expected to remove {} at tail", second_value),
417 }
418
419 match list.get(1) {
420 Some(val) => assert_eq!(*val, third_value),
421 None => panic!("Expected to find {} at index 1", third_value),
422 }
423 }
424
425 #[test]
426 fn create_numeric_list() {
427 let mut list = LinkedList::<i32>::new();
428 list.insert_at_tail(1);
429 list.insert_at_tail(2);
430 list.insert_at_tail(3);
431 println!("Linked List is {}", list);
432 assert_eq!(3, list.length);
433 }
434
435 #[test]
436 fn create_string_list() {
437 let mut list_str = LinkedList::<String>::new();
438 list_str.insert_at_tail("A".to_string());
439 list_str.insert_at_tail("B".to_string());
440 list_str.insert_at_tail("C".to_string());
441 println!("Linked List is {}", list_str);
442 assert_eq!(3, list_str.length);
443 }
444
445 #[test]
446 fn get_by_index_in_numeric_list() {
447 let mut list = LinkedList::<i32>::new();
448 list.insert_at_tail(1);
449 list.insert_at_tail(2);
450 println!("Linked List is {}", list);
451 let retrived_item = list.get(1);
452 assert!(retrived_item.is_some());
453 assert_eq!(2 as i32, *retrived_item.unwrap());
454 }
455
456 #[test]
457 fn get_by_index_in_string_list() {
458 let mut list_str = LinkedList::<String>::new();
459 list_str.insert_at_tail("A".to_string());
460 list_str.insert_at_tail("B".to_string());
461 println!("Linked List is {}", list_str);
462 let retrived_item = list_str.get(1);
463 assert!(retrived_item.is_some());
464 assert_eq!("B", *retrived_item.unwrap());
465 }
466}