use std::fmt;
// Node for linked list stack
struct Node<T> {
data: T,
next: Option<Box<Node<T>>>,
}
// Linked list stack
struct LinkedListStack<T> {
top: Option<Box<Node<T>>>,
}
impl<T> LinkedListStack<T> {
fn new() -> Self {
LinkedListStack { top: None }
}
fn push(&mut self, value: T) {
let new_node = Box::new(Node {
data: value,
next: self.top.take(), // link new node to current top
});
self.top = Some(new_node); // update top pointer
}
fn pop(&mut self) -> Option<T> {
self.top.take().map(|node| {
self.top = node.next; // move top to next node
node.data
})
}
}
impl<T: fmt::Display> fmt::Display for LinkedListStack<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut curr = &self.top;
while let Some(node) = curr {
write!(f, "{} -> ", node.data)?;
curr = &node.next;
}
write!(f, "null")
}
}
// Array stack
struct ArrayStack<T> {
data: Vec<T>,
capacity: usize,
}
impl<T> ArrayStack<T> {
fn new(capacity: usize) -> Self {
ArrayStack {
data: Vec::with_capacity(capacity),
capacity,
}
}
fn push(&mut self, value: T) -> Result<(), &str> {
if self.data.len() == self.capacity {
return Err("Stack overflow");
}
self.data.push(value);
Ok(())
}
fn pop(&mut self) -> Option<T> {
self.data.pop()
}
}
impl<T: fmt::Display> fmt::Display for ArrayStack<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for val in &self.data {
write!(f, "{} -> ", val)?;
}
write!(f, "null")
}
}
fn main() {
// Start with 1,2,3 in both stacks
let mut array_stack = ArrayStack::new(5);
array_stack.push(1).unwrap();
array_stack.push(2).unwrap();
array_stack.push(3).unwrap();
let mut linked_stack = LinkedListStack::new();
linked_stack.push(1);
linked_stack.push(2);
linked_stack.push(3);
println!("Initial Array Stack: {}", array_stack);
println!("Initial Linked List Stack: {}", linked_stack);
// Push 4
array_stack.push(4).unwrap();
linked_stack.push(4);
println!("After pushing 4:");
println!("Array Stack: {}", array_stack);
println!("Linked List Stack: {}", linked_stack);
// Pop one element
let popped_array = array_stack.pop();
let popped_linked = linked_stack.pop();
println!("After popping one element:");
println!("Array Stack: {}", array_stack);
println!("Linked List Stack: {}", linked_stack);
println!("Popped from array stack: {:?}", popped_array);
println!("Popped from linked list stack: {:?}", popped_linked);
}
self.top = Some(new_node); // update top pointer
update top pointer to new node for push in linked list
self.top = node.next; // move top to next node
move top pointer down to next node for pop in linked list
if self.data.len() == self.capacity { return Err("Stack overflow"); }
check for overflow before push in array stack
add value at end of array for push
remove last element from array for pop
Initial Array Stack: 1 -> 2 -> 3 -> null
Initial Linked List Stack: 3 -> 2 -> 1 -> null
After pushing 4:
Array Stack: 1 -> 2 -> 3 -> 4 -> null
Linked List Stack: 4 -> 3 -> 2 -> 1 -> null
After popping one element:
Array Stack: 1 -> 2 -> 3 -> null
Linked List Stack: 3 -> 2 -> 1 -> null
Popped from array stack: Some(4)
Popped from linked list stack: Some(4)