use std::rc::Rc;
use std::cell::RefCell;
#[derive(Debug)]
struct SinglyNode {
val: i32,
next: Option<Rc<RefCell<SinglyNode>>>,
}
#[derive(Debug)]
struct DoublyNode {
val: i32,
next: Option<Rc<RefCell<DoublyNode>>>,
prev: Option<Rc<RefCell<DoublyNode>>>,
}
// Delete node with value 2 in singly linked list
fn delete_singly(head: &Option<Rc<RefCell<SinglyNode>>>, val: i32) -> Option<Rc<RefCell<SinglyNode>>> {
let mut dummy = Rc::new(RefCell::new(SinglyNode { val: 0, next: head.clone() }));
let mut curr = dummy.clone();
while let Some(next_node) = curr.borrow().next.clone() {
if next_node.borrow().val == val {
// Skip node with val
curr.borrow_mut().next = next_node.borrow().next.clone();
break;
}
curr = next_node;
}
dummy.borrow().next.clone()
}
// Delete node with value 2 in doubly linked list
fn delete_doubly(head: &Option<Rc<RefCell<DoublyNode>>>, val: i32) -> Option<Rc<RefCell<DoublyNode>>> {
let mut curr = head.clone();
while let Some(node) = curr.clone() {
if node.borrow().val == val {
let prev = node.borrow().prev.clone();
let next = node.borrow().next.clone();
if let Some(p) = prev {
p.borrow_mut().next = next.clone();
}
if let Some(n) = next {
n.borrow_mut().prev = prev.clone();
}
// If deleting head
if prev.is_none() {
return next;
}
break;
}
curr = node.borrow().next.clone();
}
head.clone()
}
fn print_singly(head: &Option<Rc<RefCell<SinglyNode>>>) {
let mut curr = head.clone();
while let Some(node) = curr {
print!("{} -> ", node.borrow().val);
curr = node.borrow().next.clone();
}
println!("null");
}
fn print_doubly_forward(head: &Option<Rc<RefCell<DoublyNode>>>) {
let mut curr = head.clone();
while let Some(node) = curr {
print!("{} -> ", node.borrow().val);
curr = node.borrow().next.clone();
}
println!("null");
}
fn print_doubly_backward(tail: &Option<Rc<RefCell<DoublyNode>>>) {
let mut curr = tail.clone();
while let Some(node) = curr {
print!("{} -> ", node.borrow().val);
curr = node.borrow().prev.clone();
}
println!("null");
}
fn main() {
// Singly linked list: 1->2->3->null
let node3 = Rc::new(RefCell::new(SinglyNode { val: 3, next: None }));
let node2 = Rc::new(RefCell::new(SinglyNode { val: 2, next: Some(node3.clone()) }));
let node1 = Rc::new(RefCell::new(SinglyNode { val: 1, next: Some(node2.clone()) }));
let head_singly = Some(node1.clone());
println!("Singly Linked List before deletion:");
print_singly(&head_singly);
let head_singly = delete_singly(&head_singly, 2);
println!("Singly Linked List after deleting 2:");
print_singly(&head_singly);
// Doubly linked list: 1<->2<->3
let node3_d = Rc::new(RefCell::new(DoublyNode { val: 3, next: None, prev: None }));
let node2_d = Rc::new(RefCell::new(DoublyNode { val: 2, next: Some(node3_d.clone()), prev: None }));
node3_d.borrow_mut().prev = Some(node2_d.clone());
let node1_d = Rc::new(RefCell::new(DoublyNode { val: 1, next: Some(node2_d.clone()), prev: None }));
node2_d.borrow_mut().prev = Some(node1_d.clone());
let head_doubly = Some(node1_d.clone());
println!("Doubly Linked List before deletion:");
print_doubly_forward(&head_doubly);
let head_doubly = delete_doubly(&head_doubly, 2);
println!("Doubly Linked List after deleting 2:");
print_doubly_forward(&head_doubly);
// Move backward from tail (node 3)
println!("Doubly Linked List backward from tail:");
print_doubly_backward(&Some(node3_d.clone()));
}
while let Some(next_node) = curr.borrow().next.clone() { if next_node.borrow().val == val { curr.borrow_mut().next = next_node.borrow().next.clone(); break; } curr = next_node; }
Traverse singly linked list to find node before target and skip target node
while let Some(node) = curr.clone() { if node.borrow().val == val { let prev = node.borrow().prev.clone(); let next = node.borrow().next.clone(); if let Some(p) = prev { p.borrow_mut().next = next.clone(); } if let Some(n) = next { n.borrow_mut().prev = prev.clone(); } if prev.is_none() { return next; } break; } curr = node.borrow().next.clone(); }
Traverse doubly linked list to find target node and update prev and next pointers to remove it
print_doubly_backward(&Some(node3_d.clone()));
Traverse backward from tail using prev pointers
Singly Linked List before deletion:
1 -> 2 -> 3 -> null
Singly Linked List after deleting 2:
1 -> 3 -> null
Doubly Linked List before deletion:
1 -> 2 -> 3 -> null
Doubly Linked List after deleting 2:
1 -> 3 -> null
Doubly Linked List backward from tail:
3 -> 1 -> null