I have the following implementation for a Doubly Linked List ->
struct Node<T> {
value: T,
next: Option<Rc<RefCell<Node<T>>>>,
prev: Option<Weak<RefCell<Node<T>>>>,
}
impl<T> Node<T> {
fn new(value: T) -> Self {
Node {
value,
next: None,
prev: None,
}
}
}
impl<T> From<Node<T>> for Option<Rc<RefCell<Node<T>>>> {
fn from(node: Node<T>) -> Self { Some(Rc::new(RefCell::new(node))) }
}
type NodePtr<T> = Rc<RefCell<Node<T>>>;
pub struct DoublyLinkedList<T> {
head: Option<NodePtr<T>>,
tail: Option<NodePtr<T>>,
}
However, I have difficulty implementing an algorithm to reverse the linked list.
I tried
pub fn reverse(&mut self) {
let mut current_node = self.head.clone();
while let Some(current) = current_node {
let mut current_borrowed = current.borrow_mut();
std::mem::swap(&mut current_borrowed.next, &mut current_borrowed.prev);
current_node = current_borrowed.prev.upgrade();
}
std::mem::swap(&mut self.head, &mut self.tail);
}
But this doesn't work because current_borrowed.prev is Option<Weak<RefCell<Node<T>>>>, and I cannot upgrade it or downgrade current_borrowed.next.
O(n)extra space though, as you remove one element you have n-1 elements in the first list and 1 element in the other then (n-2, 2), … if you add that up at each step you use exactlyO(n)