project/datastructures/linear/
sll.rs1use std::fmt::Debug;
2use std::ptr;
3
4use crate::datastructures::linear::LL;
5use crate::datastructures::nodes::DNode;
6
7pub struct SLL<T> {
9 len: usize,
10 head: *mut DNode<T>,
11 tail: *mut DNode<T>,
12}
13
14impl<T> Default for SLL<T> {
15 fn default() -> Self {
16 Self { len: 0, head: ptr::null_mut(), tail: ptr::null_mut() }
17 }
18}
19
20impl<T> From<Box<DNode<T>>> for SLL<T> {
21 fn from(node: Box<DNode<T>>) -> Self {
22 let node = Box::into_raw(node);
23
24 unsafe {
25 (*node).set_next(ptr::null_mut());
26 (*node).set_prev(ptr::null_mut());
27 }
28
29 Self { len: 1, head: node, tail: node }
30 }
31}
32
33impl<T> LL<T> for SLL<T> {
34 fn len(&self) -> usize {
35 self.len
36 }
37
38 fn head(&self) -> *mut DNode<T> {
39 self.head
40 }
41
42 fn tail(&self) -> *mut DNode<T> {
43 self.tail
44 }
45
46 fn delete_at_index(&mut self, index: usize) -> Option<T> {
47 let len = self.len();
48
49 if len == 0 {
50 None
51 } else if index < len {
52 let mut current_prev = ptr::null_mut();
53 let mut current = self.head;
54
55 for _ in 0..index {
56 current_prev = current;
57 current = unsafe { (*current).get_next() };
58 }
59
60 let (current_data, current_next, _) =
61 unsafe { Box::from_raw(current) }.unpack();
62
63 if !current_prev.is_null() {
64 unsafe { (*current_prev).set_next(current_next) };
65 }
66
67 if index == 0 {
68 self.head = current_next;
69 } else if index == len - 1 {
70 self.tail = current_prev;
71 }
72
73 self.len -= 1;
74
75 Some(current_data)
76 } else {
77 panic!("deletion index (is {index}) should be < len (is {len})");
78 }
79 }
80
81 fn insert(&mut self, data: T, index: usize) {
82 let len = self.len;
83
84 if len == 0 {
85 let node = Box::into_raw(Box::new(DNode::from(data)));
86
87 self.head = node;
88 self.tail = node;
89 self.len += 1;
90 } else if index < len {
91 let mut current_prev = ptr::null_mut();
92 let mut current = self.head;
93
94 for _ in 0..index {
95 current_prev = current;
96 current = unsafe { (*current).get_next() };
97 }
98
99 let node = Box::into_raw(Box::new(DNode::from((
100 data,
101 current,
102 ptr::null_mut(),
103 ))));
104
105 match index {
106 0 => {
107 self.head = node;
108 },
109 _ => unsafe {
110 (*current_prev).set_next(node);
111 },
112 }
113
114 self.len += 1;
115 } else if index == len {
116 let node = Box::into_raw(Box::new(DNode::from((
117 data,
118 ptr::null_mut(),
119 ptr::null_mut(),
120 ))));
121
122 unsafe { (*self.tail).set_next(node) };
123
124 self.tail = node;
125 self.len += 1;
126 } else {
127 panic!("insertion index (is {index}) should be <= len (is {len})");
128 }
129 }
130
131 fn print_addresses(&self)
132 where
133 T: Debug,
134 {
135 let mut current = self.head();
136
137 for _ in 0..self.len() {
138 let data = unsafe { (*current).get_data() };
139 let next = unsafe { (*current).get_next() };
140 let prev = unsafe { (*current).get_prev() };
141 println!("{current:?} | data={data:?} next={next:?} prev={prev:?}");
142
143 assert!(!current.is_null());
144 current = unsafe { (*current).get_next() };
149 }
150 }
151}
152
153#[cfg(test)]
154mod tests {
155 use super::LL;
156 use super::SLL;
157 use crate::datastructures::nodes::DNode;
158
159 #[test]
160 fn test() {
161 let mut ll = SLL::default();
162
163 ll.insert_head(1);
164 assert_eq!(ll.iter_once().collect::<Vec<&usize>>(), &[&1]);
165
166 ll.insert_head(4);
167 assert_eq!(ll.iter_once().collect::<Vec<&usize>>(), &[&4, &1]);
168
169 ll.insert_tail(2);
170 assert_eq!(ll.iter_once().collect::<Vec<&usize>>(), &[&4, &1, &2]);
171 assert!(!ll.is_sorted());
172
173 ll.insert_sorted(3);
174 assert_eq!(ll.iter_once().collect::<Vec<&usize>>(), &[&1, &2, &3, &4]);
175
176 ll.tail();
177 ll.print();
178
179 ll.delete(&3);
180 assert_eq!(ll.iter_once().collect::<Vec<&usize>>(), &[&1, &2, &4]);
181
182 ll.clear();
183 assert_eq!(ll.iter_once().count(), 0);
184
185 let mut ll = SLL::from(Box::new(DNode::from(0)));
186 assert_eq!(ll.len(), 1);
187
188 ll.delete_tail();
189 }
190}