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