use std::cell::RefCell;
use std::rc::{Rc, Weak};
type Link<T> = Option<Rc<RefCell<Node<T>>>>;
#[derive(Debug)]
struct Node<T> {
value: T,
prev: Option<Weak<RefCell<Node<T>>>>,
next: Link<T>,
}
struct List<T> {
head: Link<T>,
tail: Link<T>,
}
impl<T: std::fmt::Debug> List<T> {
fn new() -> Self {
Self { head: None, tail: None }
}
fn push_back(&mut self, value: T) {
let new_node = Rc::new(RefCell::new(Node {
value,
prev: None,
next: None,
}));
match self.tail.take() {
Some(old_tail) => {
old_tail.borrow_mut().next = Some(new_node.clone());
new_node.borrow_mut().prev = Some(Rc::downgrade(&old_tail));
self.tail = Some(new_node);
}
None => {
self.head = Some(new_node.clone());
self.tail = Some(new_node);
}
}
}
fn pop_back(&mut self) -> Option<T> {
self.tail.take().map(|old_tail| {
{
let mut old_tail_ref = old_tail.borrow_mut();
match old_tail_ref.prev.take() {
Some(prev_weak) => {
if let Some(prev) = prev_weak.upgrade() {
prev.borrow_mut().next = None;
self.tail = Some(prev);
}
}
None => {
self.head = None;
}
}
} // 👈 old_tail_ref 在这里 drop
println!(
"Dropping strong={}, weak={}",
Rc::strong_count(&old_tail),
Rc::weak_count(&old_tail)
);
Rc::try_unwrap(old_tail)
.ok()
.unwrap()
.into_inner()
.value
})
}
fn print_counts(&self) {
if let Some(ref head) = self.head {
println!(
"HEAD strong={}, weak={}",
Rc::strong_count(head),
Rc::weak_count(head)
);
}
if let Some(ref tail) = self.tail {
println!(
"TAIL strong={}, weak={}",
Rc::strong_count(tail),
Rc::weak_count(tail)
);
}
}
}
fn main() {
let mut list = List::new();
println!("== push 1 ==");
list.push_back(1);
list.print_counts();
println!("== push 2 ==");
list.push_back(2);
list.print_counts();
println!("== push 3 ==");
list.push_back(3);
list.print_counts();
println!("== pop ==");
list.pop_back();
list.print_counts();
println!("== pop ==");
list.pop_back();
list.print_counts();
println!("== pop ==");
list.pop_back();
list.print_counts();
}
rust数据结构双链表实现
最新推荐文章于 2026-06-21 19:50:00 发布

451

被折叠的 条评论
为什么被折叠?



