From Wikipedia, a stack is an abstract data type that serves as a collection of elements, with two main principal operations, Push and Pop.

Properties

  • Push O(1)
  • Pop head.data O(1) tail.data O(n)
  • Peek O(1)
  1. // the public struct can hide the implementation detail
  2. pub struct Stack<T> {
  3. head: Link<T>,
  4. }
  5. type Link<T> = Option<Box<Node<T>>>;
  6. struct Node<T> {
  7. elem: T,
  8. next: Link<T>,
  9. }
  10. impl<T> Stack<T> {
  11. // Self is an alias for Stack
  12. // We implement associated function name new for single-linked-list
  13. pub fn new() -> Self {
  14. // for new function we need to return a new instance
  15. Self {
  16. // we refer to variants of an enum using :: the namespacing operator
  17. head: None,
  18. } // we need to return the variant, so there without the ;
  19. }
  20. // As we know the primary forms that self can take: self, &mut self and &self, push will change the linked list
  21. // so we need &mut
  22. // The push method which the signature's first parameter is self
  23. pub fn push(&mut self, elem: T) {
  24. let new_node = Box::new(Node {
  25. elem,
  26. next: self.head.take(),
  27. });
  28. // don't forget replace the head with new node for stack
  29. self.head = Some(new_node);
  30. }
  31. ///
  32. /// In pop function, we trying to:
  33. /// * check if the list is empty, so we use enum Option<T>, it can either be Some(T) or None
  34. /// * if it's empty, return None
  35. /// * if it's not empty
  36. /// * remove the head of the list
  37. /// * remove its elem
  38. /// * replace the list's head with its next
  39. /// * return Some(elem), as the situation if need
  40. ///
  41. /// so, we need to remove the head, and return the value of the head
  42. pub fn pop(&mut self) -> Result<T, &str> {
  43. match self.head.take() {
  44. None => Err("Stack is empty"),
  45. Some(node) => {
  46. self.head = node.next;
  47. Ok(node.elem)
  48. }
  49. }
  50. }
  51. pub fn is_empty(&self) -> bool {
  52. // Returns true if the option is a [None] value.
  53. self.head.is_none()
  54. }
  55. pub fn peek(&self) -> Option<&T> {
  56. // Converts from &Option<T> to Option<&T>.
  57. match self.head.as_ref() {
  58. None => None,
  59. Some(node) => Some(&node.elem),
  60. }
  61. }
  62. pub fn peek_mut(&mut self) -> Option<&mut T> {
  63. match self.head.as_mut() {
  64. None => None,
  65. Some(node) => Some(&mut node.elem),
  66. }
  67. }
  68. pub fn into_iter_for_stack(self) -> IntoIter<T> {
  69. IntoIter(self)
  70. }
  71. pub fn iter(&self) -> Iter<'_, T> {
  72. Iter {
  73. next: self.head.as_deref(),
  74. }
  75. }
  76. // '_ is the "explicitly elided lifetime" syntax of Rust
  77. pub fn iter_mut(&mut self) -> IterMut<'_, T> {
  78. IterMut {
  79. next: self.head.as_deref_mut(),
  80. }
  81. }
  82. }
  83. impl<T> Default for Stack<T> {
  84. fn default() -> Self {
  85. Self::new()
  86. }
  87. }
  88. /// The drop method of singly linked list. There's a question that do we need to worry about cleaning up our list?
  89. /// As we all know the ownership and borrow mechanism, so we know the type will clean automatically after it goes out the scope,
  90. /// this implement by the Rust compiler automatically did which mean add trait `drop` for the automatically.
  91. ///
  92. /// So, the complier will implements Drop for `List->Link->Box<Node> ->Node` automatically and tail recursive to clean the elements
  93. /// one by one. And we know the recursive will stop at Box<Node>
  94. /// https://rust-unofficial.github.io/too-many-lists/first-drop.html
  95. ///
  96. /// As we know we can't drop the contents of the Box after deallocating, so we need to manually write the iterative drop
  97. impl<T> Drop for Stack<T> {
  98. fn drop(&mut self) {
  99. let mut cur_link = self.head.take();
  100. while let Some(mut boxed_node) = cur_link {
  101. cur_link = boxed_node.next.take();
  102. // boxed_node goes out of scope and gets dropped here;
  103. // but its Node's `next` field has been set to None
  104. // so no unbound recursion occurs.
  105. }
  106. }
  107. }
  108. /// Rust has nothing like a yield statement, and there's actually 3 different kinds of iterator should to implement
  109. // Collections are iterated in Rust using the Iterator trait, we define a struct implement Iterator
  110. pub struct IntoIter<T>(Stack<T>);
  111. impl<T> Iterator for IntoIter<T> {
  112. // This is declaring that every implementation of iterator has an associated type called Item
  113. type Item = T;
  114. // the reason iterator yield Option<self::Item> is because the interface coalesces the `has_next` and `get_next` concepts
  115. fn next(&mut self) -> Option<Self::Item> {
  116. self.0.pop().ok()
  117. }
  118. }
  119. pub struct Iter<'a, T> {
  120. next: Option<&'a Node<T>>,
  121. }
  122. impl<'a, T> Iterator for Iter<'a, T> {
  123. type Item = &'a T;
  124. fn next(&mut self) -> Option<Self::Item> {
  125. self.next.map(|node| {
  126. // as_deref: Converts from Option<T> (or &Option<T>) to Option<&T::Target>.
  127. self.next = node.next.as_deref();
  128. &node.elem
  129. })
  130. }
  131. }
  132. pub struct IterMut<'a, T> {
  133. next: Option<&'a mut Node<T>>,
  134. }
  135. impl<'a, T> Iterator for IterMut<'a, T> {
  136. type Item = &'a mut T;
  137. fn next(&mut self) -> Option<Self::Item> {
  138. // we add take() here due to &mut self isn't Copy(& and Option<&> is Copy)
  139. self.next.take().map(|node| {
  140. self.next = node.next.as_deref_mut();
  141. &mut node.elem
  142. })
  143. }
  144. }
  145. #[cfg(test)]
  146. mod test_stack {
  147. use super::*;
  148. #[test]
  149. fn basics() {
  150. let mut list = Stack::new();
  151. assert_eq!(list.pop(), Err("Stack is empty"));
  152. list.push(1);
  153. list.push(2);
  154. list.push(3);
  155. assert_eq!(list.pop(), Ok(3));
  156. assert_eq!(list.pop(), Ok(2));
  157. list.push(4);
  158. list.push(5);
  159. assert_eq!(list.is_empty(), false);
  160. assert_eq!(list.pop(), Ok(5));
  161. assert_eq!(list.pop(), Ok(4));
  162. assert_eq!(list.pop(), Ok(1));
  163. assert_eq!(list.pop(), Err("Stack is empty"));
  164. assert_eq!(list.is_empty(), true);
  165. }
  166. #[test]
  167. fn peek() {
  168. let mut list = Stack::new();
  169. assert_eq!(list.peek(), None);
  170. list.push(1);
  171. list.push(2);
  172. list.push(3);
  173. assert_eq!(list.peek(), Some(&3));
  174. assert_eq!(list.peek_mut(), Some(&mut 3));
  175. match list.peek_mut() {
  176. None => None,
  177. Some(value) => Some(*value = 42),
  178. };
  179. assert_eq!(list.peek(), Some(&42));
  180. assert_eq!(list.pop(), Ok(42));
  181. }
  182. #[test]
  183. fn into_iter() {
  184. let mut list = Stack::new();
  185. list.push(1);
  186. list.push(2);
  187. list.push(3);
  188. let mut iter = list.into_iter_for_stack();
  189. assert_eq!(iter.next(), Some(3));
  190. assert_eq!(iter.next(), Some(2));
  191. assert_eq!(iter.next(), Some(1));
  192. assert_eq!(iter.next(), None);
  193. }
  194. #[test]
  195. fn iter() {
  196. let mut list = Stack::new();
  197. list.push(1);
  198. list.push(2);
  199. list.push(3);
  200. let mut iter = list.iter();
  201. assert_eq!(iter.next(), Some(&3));
  202. assert_eq!(iter.next(), Some(&2));
  203. assert_eq!(iter.next(), Some(&1));
  204. }
  205. #[test]
  206. fn iter_mut() {
  207. let mut list = Stack::new();
  208. list.push(1);
  209. list.push(2);
  210. list.push(3);
  211. let mut iter = list.iter_mut();
  212. assert_eq!(iter.next(), Some(&mut 3));
  213. assert_eq!(iter.next(), Some(&mut 2));
  214. assert_eq!(iter.next(), Some(&mut 1));
  215. }
  216. }