use std::rc::Rc;
use std::cell::RefCell;
#[derive(Debug)]
struct Node {
val: i32,
prev: Option<Rc<RefCell<Node>>>,
next: Option<Rc<RefCell<Node>>>,
}
impl Node {
fn new(val: i32) -> Rc<RefCell<Node>> {
Rc::new(RefCell::new(Node { val, prev: None, next: None }))
}
}
struct DoublyLinkedList {
head: Option<Rc<RefCell<Node>>>,
}
impl DoublyLinkedList {
fn new() -> Self {
DoublyLinkedList { head: None }
}
fn append(&mut self, val: i32) {
let new_node = Node::new(val);
match self.head.clone() {
None => self.head = Some(new_node),
Some(head) => {
let mut tail = head.clone();
while let Some(next) = tail.borrow().next.clone() {
tail = next;
}
tail.borrow_mut().next = Some(new_node.clone());
new_node.borrow_mut().prev = Some(tail);
}
}
}
fn insert_at_position(&mut self, val: i32, pos: usize) {
let new_node = Node::new(val);
if pos == 0 {
if let Some(head) = self.head.take() {
new_node.borrow_mut().next = Some(head.clone());
head.borrow_mut().prev = Some(new_node.clone());
}
self.head = Some(new_node);
return;
}
let mut current = match self.head.clone() {
None => return, // empty list, do nothing
Some(node) => node,
};
let mut index = 0;
while index < pos - 1 {
let next = current.borrow().next.clone();
match next {
Some(next_node) => current = next_node,
None => return, // position out of bounds
}
index += 1;
}
let next_node = current.borrow().next.clone();
current.borrow_mut().next = Some(new_node.clone());
new_node.borrow_mut().prev = Some(current.clone());
new_node.borrow_mut().next = next_node.clone();
if let Some(next) = next_node {
next.borrow_mut().prev = Some(new_node.clone());
}
}
fn print_list(&self) {
let mut current = self.head.clone();
while let Some(node) = current {
print!("{}", node.borrow().val);
current = node.borrow().next.clone();
if current.is_some() {
print!(" ↔ ");
}
}
println!();
}
}
fn main() {
let mut dll = DoublyLinkedList::new();
dll.append(1);
dll.append(2);
dll.append(3);
dll.insert_at_position(4, 2);
dll.print_list();
}while let Some(next) = tail.borrow().next.clone() {
tail = next;
}
advance tail to last node to append new node
tail.borrow_mut().next = Some(new_node.clone());
new_node.borrow_mut().prev = Some(tail);
link new node after tail for append
if pos == 0 {
if let Some(head) = self.head.take() {
new_node.borrow_mut().next = Some(head.clone());
head.borrow_mut().prev = Some(new_node.clone());
}
self.head = Some(new_node);
return;
}
handle insertion at head by adjusting pointers
while index < pos - 1 {
let next = current.borrow().next.clone();
match next {
Some(next_node) => current = next_node,
None => return,
}
index += 1;
}
traverse to node before insertion position
let next_node = current.borrow().next.clone();
current.borrow_mut().next = Some(new_node.clone());
new_node.borrow_mut().prev = Some(current.clone());
new_node.borrow_mut().next = next_node.clone();
if let Some(next) = next_node {
next.borrow_mut().prev = Some(new_node.clone());
}
insert new node by linking it between current and next_node