use std::rc::Rc;
use std::cell::RefCell;
#[derive(Debug)]
struct Node {
value: i32,
next: Option<Rc<RefCell<Node>>>,
prev: Option<Rc<RefCell<Node>>>,
}
#[derive(Debug)]
struct Dequeue {
head: Option<Rc<RefCell<Node>>>,
tail: Option<Rc<RefCell<Node>>>,
}
impl Dequeue {
fn new() -> Self {
Dequeue { head: None, tail: None }
}
fn add_front(&mut self, val: i32) {
let new_node = Rc::new(RefCell::new(Node { value: val, next: self.head.clone(), prev: None }));
if let Some(old_head) = &self.head {
old_head.borrow_mut().prev = Some(new_node.clone());
} else {
self.tail = Some(new_node.clone());
}
self.head = Some(new_node);
}
fn add_back(&mut self, val: i32) {
let new_node = Rc::new(RefCell::new(Node { value: val, next: None, prev: self.tail.clone() }));
if let Some(old_tail) = &self.tail {
old_tail.borrow_mut().next = Some(new_node.clone());
} else {
self.head = Some(new_node.clone());
}
self.tail = Some(new_node);
}
fn remove_front(&mut self) -> Option<i32> {
self.head.take().map(|old_head| {
if let Some(next_node) = &old_head.borrow().next {
next_node.borrow_mut().prev = None;
self.head = Some(next_node.clone());
} else {
self.tail = None;
}
Rc::try_unwrap(old_head).ok().unwrap().into_inner().value
})
}
fn remove_back(&mut self) -> Option<i32> {
self.tail.take().map(|old_tail| {
if let Some(prev_node) = &old_tail.borrow().prev {
prev_node.borrow_mut().next = None;
self.tail = Some(prev_node.clone());
} else {
self.head = None;
}
Rc::try_unwrap(old_tail).ok().unwrap().into_inner().value
})
}
fn print(&self) {
let mut current = self.head.clone();
while let Some(node) = current {
print!("{} -> ", node.borrow().value);
current = node.borrow().next.clone();
}
println!("null");
}
}
fn main() {
let mut dq = Dequeue::new();
dq.add_front(1);
dq.add_back(2);
dq.remove_front();
dq.add_front(3);
dq.print();
}let new_node = Rc::new(RefCell::new(Node { value: val, next: self.head.clone(), prev: None }));
create new node pointing next to current head for add_front
old_head.borrow_mut().prev = Some(new_node.clone());
link old head's prev to new node to maintain double links
self.head = Some(new_node);
update head pointer to new node
let new_node = Rc::new(RefCell::new(Node { value: val, next: None, prev: self.tail.clone() }));
create new node pointing prev to current tail for add_back
old_tail.borrow_mut().next = Some(new_node.clone());
link old tail's next to new node
self.tail = Some(new_node);
update tail pointer to new node
self.head.take().map(|old_head| { ... })
remove front node and update head pointer
self.tail.take().map(|old_tail| { ... })
remove back node and update tail pointer