571
社区成员
发帖
与我相关
我的任务
分享
pub enum Node<T> {
Cons(T, Rc<RefCell<Node<T>>>, Rc<RefCell<Node<T>>>),
Nil,
}
//右迭代器
pub mod iter_r {
use std::{rc::Rc, cell::RefCell};
use super::Node::{*, self};
pub struct IterR<T> {
cur: Rc<RefCell<Node<T>>>
}
impl<T> IterR<T> {
pub fn new(cur: Rc<RefCell<Node<T>>>) -> IterR<T> {
IterR { cur }
}
}
impl<T> Iterator for IterR<T> {
type Item = Rc<RefCell<Node<T>>>;
fn next(&mut self) -> Option<Self::Item> {
let self_clone = self.cur.clone();
let tmp = &*self_clone.borrow();
match tmp {
Cons(_, _, r) => {
let ret = Some(self.cur.clone());
self.cur = r.clone();
ret
}
Nil => {
None
}
}
}
}
}
左迭代器同理,不再赘述,详见代码链接
pub struct List<T> {
head: Rc<RefCell<Node<T>>>,
tail: Rc<RefCell<Node<T>>>,
size: u32,
}
//创建新链表
pub fn new() -> List<T> {
List {
head: Rc::new(RefCell::new(Nil)),
tail: Rc::new(RefCell::new(Nil)),
size: 0
}
}
//从vector创建新链表
pub fn from(vec: Vec<T>) -> List<T> {
let mut list = List::new();
for e in vec {
list.push_back(e);
}
list
}
//返回链表大小
pub fn size(&self) -> u32 {
self.size
}
//返回右迭代器
pub fn iter_r(&self) -> IterR<T> {
IterR::new(self.head.clone())
}
//返回左迭代器
pub fn iter_l(&self) -> IterL<T> {
IterL::new(self.tail.clone())
}
//向右遍历链表
pub fn traverse_r(&self)
where T: Display {
for e in self.iter_r() {
//let tmp = e.borrow();
if let Cons(val, _, _) = &*e.borrow() {
print!("{} ", val);
}
}
println!();
}
//向左遍历链表
pub fn traverse_l(&self)
where T: Display {
for e in self.iter_l() {
//let tmp = e.borrow();
if let Cons(val, _, _) = &*e.borrow() {
print!("{} ", val);
}
}
println!();
}
//尾插
pub fn push_back(&mut self, val: T) {
let nil = Rc::new(RefCell::new(Nil));
let new_node = Rc::new(RefCell::new(Cons(val, self.tail.clone(), nil)));
let tail_clone = self.tail.clone();
let tmp = &mut *tail_clone.borrow_mut();
match tmp {
Cons(_, _, r) => {
*r = new_node.clone();
self.tail = new_node.clone();
self.size += 1;
}
Nil => {
self.head = new_node.clone();
self.tail = new_node.clone();
self.size = 1;
}
}
}
//头插
pub fn push_front(&mut self, val: T) {
let nil = Rc::new(RefCell::new(Nil));
let new_node = Rc::new(RefCell::new(Cons(val, nil, self.head.clone())));
let head_clone = self.head.clone();
let tmp = &mut *head_clone.borrow_mut();
match tmp {
Cons(_, l, _) => {
*l = new_node.clone();
self.head = new_node.clone();
self.size += 1;
}
Nil => {
self.head = new_node.clone();
self.tail = new_node.clone();
self.size = 1;
}
}
}
//当前节点之前插入一个节点
pub fn insert_l(&mut self, cur: Rc<RefCell<Node<T>>>, val: T) {
let mut borrow = cur.borrow_mut();
let tmp = &mut *borrow;
match tmp {
Nil => panic!("当前节点无效(cur is a nil node)."),
Cons(_, l, _) => {
if Rc::ptr_eq(&cur, &self.head) {
//println!("yes");
drop(borrow); //释放RefCell借用
self.push_front(val);
} else {
let lnode = l.clone();
let new_node = Rc::new(RefCell::new(Cons(val, lnode.clone(), cur.clone())));
let tmp = &mut *lnode.borrow_mut();
if let Cons(_, _, r) = tmp {
*r = new_node.clone();
}
//let tmp = &mut *cur.borrow_mut();
//if let Cons(_, l, _) = tmp {
*l = new_node.clone();
//}
self.size += 1;
}
}
}
}
在当前节点之后插入详见代码链接
//从左向右查找key第一次出现的节点
pub fn find_r(&self, key: &T) -> Rc<RefCell<Node<T>>>
where T: Ord {
//todo!()
for e in self.iter_r() {
if let Cons(m_key, _, _) = &*e.borrow() {
if let Ordering::Equal = key.cmp(m_key) {
return e.clone();
}
}
}
Rc::new(RefCell::new(Nil))
}
从右往左查找详见代码链接
//删除尾节点
pub fn pop_back(&mut self) {
//let nil = Rc::new(RefCell::new(Nil));
let tail_clone = self.tail.clone();
let tmp = &mut *tail_clone.borrow_mut();
match tmp {
Cons(_, l, _) => {
let lnode = &mut *l.borrow_mut();
match lnode {
Cons(_, _, r) => {
*r = Rc::new(RefCell::new(Nil));
}
Nil => {
self.head = Rc::new(RefCell::new(Nil));
//self.tail = Rc::new(RefCell::new(Nil));
//self.size = 0;
}
}
self.tail = l.clone();
self.size -= 1;
}
Nil => {
panic!("empty link, can't pop a node");
}
}
}
删除头节点详见代码链接
//删除当前节点
pub fn remove(&mut self, cur: Rc<RefCell<Node<T>>>) {
let mut borrow = cur.borrow_mut();
let tmp = &mut *borrow;
match tmp {
Nil => panic!("当前节点无效(cur is a nil node)."),
Cons(_, l, r) => {
if Rc::ptr_eq(&cur, &self.tail) {
//println!("yes");
drop(borrow); //释放RefCell借用
self.pop_back();
} else if Rc::ptr_eq(&cur, &self.head) {
drop(borrow);
self.pop_front();
} else {
let rnode = r.clone();
let lnode = l.clone();
//let new_node = Rc::new(RefCell::new(Cons(val, cur.clone(), r.clone())));
let tmp = &mut *rnode.borrow_mut();
if let Cons(_, ll, _) = tmp {
*ll = lnode.clone();
}
let tmp = &mut *lnode.borrow_mut();
if let Cons(_, _, rr) = tmp {
*rr = rnode.clone();
}
self.size -= 1;
}
}
}
}
//修改当前节点
pub fn modify(&mut self, cur: Rc<RefCell<Node<T>>>, val: T) {
let mut borrow = cur.borrow_mut();
let tmp = &mut *borrow;
match tmp {
Nil => panic!("当前节点无效(cur is a nil node)."),
Cons(v, _, _) => {
*v = val;
}
}
}
bug:
迭代器不应该以所有权形式返回,应该以一个引用的方式,否则用户可以通过迭代器改变某个节点,
甚至插入删除一个节点,这还不会将链表的size、head、tail同时进行改变,产生严重后果。
(由于我对生命周期理解较浅,本文直接返回所有权)
注意:
增删改必须提供链表内的节点,随意传入一个节点会出错。用户不应该通过迭代器擅自修改链表,
而应该通过链表提供的接口来完成所需操作,这样的话该链表就是安全的。
作者:李阳
学号:282