Rust 链表简单实现
Rust 链表简单实现
这段时间学完两遍Rust语法后,基于《Learn Rust With Entirely Too Many Linked Lists》写的练习
单向链表1
///链表 栈实现
/// 链表节点元素
///
/// T为泛型类型,节点元素中装的T类型的数据
///
/// elem:数据域
///
/// next:指针域,指向下一个链节点
pub struct Node<T> {
elem: T,
next: Link<T>,
}
/// 链枚举
///
/// Empty:空链
///
/// More:链数据
pub enum Link<T> {
/// 空节点枚举值
Empty,
/// Box智能指针将Node放在堆空间
More(Box<Node<T>>),
}
/// 链表结构体
pub struct List<T> {
/// 头结点
head: Link<T>,
}
// 实现定义
impl<T> Drop for List<T> {
/// List 结构 Drop特征实现
fn drop(&mut self) {
// 将头结点置为Empty,并返回头结点的值作为当前节点
// cur_link退出drop作用域后会被自动drop
let mut cur_link: Link<T> = std::mem::replace(&mut self.head, Link::Empty);
// while循环,匹配模式,直到匹配到None,退出循环
while let Link::More(mut box_node) = cur_link {
// 将box_node置为Empty,并返回box_node.next作为当前节点
// boxed_node 在这里超出作用域并被 drop,
// 由于它的 `next` 字段拥有的 `Node` 被设置为 Link::Empty,
// 因此这里并不会有无边界的递归发生
cur_link = std::mem::replace(&mut box_node.next, Link::Empty);
}
}
}
// List结构体的实现
impl<T> List<T> {
/// new函数, 返回List实例
pub fn new() -> Self {
// 构建个头结点位空的List实例,并返回
List { head: Link::Empty }
}
/// 这个push是头插实现
///
/// 执行过程如下:
///
/// 原:node2 -> node1
///
/// 新建:node3
///
/// 插入后:node3 -> node2 -> node3
///
/// 最难理解的是:next: std::mem::replace(&mut self.head, Link::Empty)
///
/// 将&mut self.head的值设置为Link::Empty,并返回&mut self.head的原值
///
/// 原&mut self.head的值就是node2的地址
///
/// 返回node2的地址,将node3的next指向node2
///
/// 将&mut self.head的值置Link::Empty
///
/// 最后将node3置为head
pub fn push(&mut self, elem: T) {
// 新建一个节点
let new_node: Box<Node<T>> = Box::new(Node {
elem,
// 将&mut self.head的值设置为Link::Empty,并返回&mut self.head的原值
// 没有交换之前,&mut self.head
next: std::mem::replace(&mut self.head, Link::Empty),
});
// 将新节点插到头结点
self.head = Link::More(new_node);
}
/// pop 函数
pub fn pop(&mut self) -> Option<T> {
// 定义result
let result: Option<T>;
// 将&mut self.head的值设置为Link::Empty,并返回&mut self.head的原值
// 将head节点返回,并将head节点置空
match std::mem::replace(&mut self.head, Link::Empty) {
Link::Empty => {
result = None;
}
Link::More(node) => {
// 将node.next置为head
self.head = node.next;
result = Some(node.elem);
}
};
// 返回值
result
}
}
#[cfg(test)]
mod test {
use super::List;
#[test]
fn basics() {
let mut list: List<i32> = List::new();
assert_eq!(list.pop(), None);
list.push(1);
list.push(2);
list.push(3);
assert_eq!(list.pop(), Some(3));
assert_eq!(list.pop(), Some(2));
list.push(4);
list.push(5);
assert_eq!(list.pop(), Some(5));
assert_eq!(list.pop(), Some(4));
assert_eq!(list.pop(), Some(1));
assert_eq!(list.pop(), None);
}
}
单向链表2
/// 链节点对象,Option别名
///
/// 智能指针Box将Node放在堆区
type Link<T> = Option<Box<Node<T>>>;
/// 转换为迭代器结构
///
/// 返回节点实例
pub struct IntoIter<T>(List<T>);
/// 迭代构造
///
/// 当持有当前节点的指针,当生成一个值后,该指针指向下一个节点
///
/// ’a生命周期意味着,Node<T>引用的生命周期要比Iter的长
///
/// 返回节点不可变引用
pub struct Iter<'a, T> {
next: Option<&'a Node<T>>,
}
/// 迭代结构
///
/// 返回节点的可变引用
pub struct IterMut<'a, T> {
next: Option<&'a mut Node<T>>,
}
/// 数据节点结构,存储泛型类型
pub struct Node<T> {
elem: T,
next: Link<T>,
}
/// 链表结构体
pub struct List<T> {
/// 头结点
head: Link<T>,
}
/// 链表实现
impl<T> List<T> {
/// 这里的生命周期'a, &self获得至少和Iter一样久
///
/// 转换为Iter对象
pub fn iter(&self) -> Iter<T> {
/*
as_ref() 和 as_mut() 用于返回内部值的引用,分别是不可变引用和可变引用。
as_deref() 和 as_deref_mut() 则用于解引用操作,将包装类型转换为内部类型的引用。
as_deref()转换为不可变引用, as_deref_mut()转换为可变引用
*/
Iter {
next: self.head.as_deref(),
}
}
/// 转换为IterMut对象
pub fn iter_mut(&mut self) -> IterMut<T> {
IterMut {
next: self.head.as_deref_mut(),
}
}
/// 链表转换为迭代器
pub fn into_iter(self) -> IntoIter<T> {
IntoIter(self)
}
// new 链表
pub fn new() -> Self {
List { head: None }
}
/// push方法
pub fn push(&mut self, elem: T) {
let new_node: Box<Node<T>> = Box::new(Node {
elem,
// take:将值取出后返回,原值置为None
next: self.head.take(),
});
// 头结点设置为新建节点
self.head = Some(new_node);
}
/// pop 方法
pub fn pop(&mut self) -> Option<T> {
// 返回头结点值,返回值为Option,进入match匹配模式
// 返回头结点的值,并将头结点的值设置为None
match self.head.take() {
// 匹配到None,直接返回None
None => None,
// 匹配到Some
Some(node) => {
// 将头结点置为node.next
self.head = node.next;
// 将头结点的值返回
Some(node.elem)
}
}
}
/// 返回头结点元素的不可变引用
pub fn peek(&self) -> Option<&T> {
// 如果不加as_ref,就会讲head节点中元素的所有权转移到map中
// 加上as_ref,将head节点中的元素的引用转移到map中
self.head.as_ref().map(|node: &Box<Node<T>>| &node.elem)
}
/// 返回头结点的可变引用
pub fn peek_mut(&mut self) -> Option<&mut T> {
// self.head 的类型为 Option<Box<Node<T>>>
self.head
// 转换为 Option<&mut Box<Node<T>>>
.as_mut()
// 最后将节点中元素的可变引用返回
.map(|node: &mut Box<Node<T>>| &mut node.elem)
}
}
/// 链表实现Drop特征
impl<T> Drop for List<T> {
fn drop(&mut self) {
// 头结点返回作为当前节点,并将原头结点设置为None
let mut cur_link: Option<Box<Node<T>>> = self.head.take();
// while 循环 定义新变量cur_node ,cur_node = cur_link
// 如果cur_node 为Some,则进入循环体
// cur_node 作用域为while循环,完成一次循环体,则当前cur_node将被自动drop
while let Some(mut cur_node) = cur_link {
// cur_node.next返回赋值为cur_link,cur_node.next设置为None
cur_link = cur_node.next.take();
}
}
}
/// 链表实例迭代器实现
impl<T> Iterator for IntoIter<T> {
// 关联类型
type Item = T;
/// 迭代器默认函数,next
fn next(&mut self) -> Option<Self::Item> {
// 为什么是0,因为IntoIter是元组结构,0是元组结构的第一个元素
// pop是已实现的弹出函数
self.0.pop()
}
}
/// 不可变引用迭代器实现
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
// self.next 类型为 Option<&Node<T>>
// map 函数是将 &Node<T> 类型的数据进行copy
// 然后在闭包中处理
self.next.map(|node: &Node<T>| {
// as_deref 函数将 Option<Box<Node<T> 类型转换为 Option<&Node<T>> 类型
// 就是将Option中的智能指针类型转换为不可变引用类型
// self.next指向 node.next.as_deref()
self.next = node.next.as_deref();
// 将元素的不可变引用返回
&node.elem
})
}
}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
// self.next类型为Option<&mut Node<T>>
// 可变引用 Option<&mut T> 没有实现copy特性,所以后面不能跟map讲可变引用的借走
// take 方法将 Option 中的值取出并返回,就不会在编译期被执行copy,使得 map 方法可以应用于该值
self.next.take().map(|node: &mut Node<T>| {
// as_deref 函数将 Option<Box<Node<T> 类型转换为 Option<&mut Node<T>> 类型
// 就是将Option中的智能指针类型转换为可变引用类型
self.next = node.next.as_deref_mut();
// 将元素的可变引用返回
&mut node.elem
})
}
}
#[cfg(test)]
mod test {
use super::{IntoIter, List};
#[test]
pub fn test1() {
let mut list: List<i32> = List::new();
list.push(1);
list.push(2);
list.push(3);
let mut iter: IntoIter<i32> = list.into_iter();
assert_eq!(iter.next(), Some(3));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), None);
}
#[test]
pub fn test() {
let mut list: List<i32> = List::new();
assert_eq!(list.pop(), None);
assert_eq!(list.peek(), None);
assert_eq!(list.peek_mut(), None);
list.push(1);
list.push(2);
list.push(3);
assert_eq!(list.peek(), Some(&3));
assert_eq!(list.peek_mut(), Some(&mut 3));
list.peek_mut().map(|value: &mut i32| *value = 42);
assert_eq!(list.peek(), Some(&42));
assert_eq!(list.pop(), Some(42));
}
}
单向链表3
// 为了链表可以被引用多次(单线程),使用Rc计数器
use std::rc::Rc;
type Link<T> = Option<Rc<Node<T>>>;
pub struct Node<T> {
elem: T,
next: Link<T>,
}
pub struct List<T> {
head: Link<T>,
}
pub struct Iter<'a, T> {
next: Option<&'a Node<T>>,
}
pub struct IterMut<'a, T> {
next: Option<&'a mut Node<T>>,
}
pub struct IntoIter<T>(List<T>);
impl<T> List<T> {
pub fn into_iter(self) -> IntoIter<T> {
IntoIter(self)
}
// Rc不支持可变引用借用,不纠结了
// pub fn iter_mut(&mut self) -> IterMut<T> {
// let mut next = None;
// if let Some(ref )
// }
pub fn iter(&self) -> Iter<T> {
Iter {
// as_deref 将智能指针类型转换为&引用类型
next: self.head.as_deref(),
}
}
/// new 关联方法
pub fn new() -> Self {
List { head: None }
}
/// 添加元素,并返回新链表
pub fn prepend(&self, elem: T) -> List<T> {
List {
head: Some(Rc::new(Node {
elem,
// 该处clone只是调用Rc的clone函数,链表引用+1
next: self.head.clone(),
})),
}
}
/// 将现有链表的首个元素移除,并返回剩余的链表
pub fn tail(&self) -> List<T> {
List {
// head的类型为 Option<Rc<Node<T>>>
head: self
.head
// as_ref:Option<Rc<Node<T>>> 类型转换为 Option<&Rc<Node<T>>> 类型
.as_ref()
// and_then: 如果选项为 None,则返回 None; 否则,使用包装的值调用 f,并返回结果
.and_then(|node: &Rc<Node<T>>| node.next.clone()),
}
}
/// 返回首个元素的引用
pub fn head(&self) -> Option<&T> {
self.head.as_ref().map(|node| &node.elem)
}
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.next.map(|node| {
self.next = node.next.as_deref();
&node.elem
})
}
}
impl<T> Iterator for IntoIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.next()
}
}
/// 链表的Drop实现
impl<T> Drop for List<T> {
fn drop(&mut self) {
let mut cur_link: Option<Rc<Node<T>>> = self.head.take();
while let Some(cur_node) = cur_link {
if let Ok(mut cur_node_0) = Rc::try_unwrap(cur_node) {
cur_link = cur_node_0.next.take();
} else {
break;
}
}
}
}
#[cfg(test)]
mod test {
use super::{Iter, List};
#[test]
pub fn test() {
let list: List<i32> = List::new();
assert_eq!(list.head(), None);
let list: List<i32> = list.prepend(1).prepend(2).prepend(3);
assert_eq!(list.head(), Some(&3));
let list: List<i32> = list.tail();
assert_eq!(list.head(), Some(&2));
let list: List<i32> = list.tail();
assert_eq!(list.head(), Some(&1));
let list: List<i32> = list.tail();
assert_eq!(list.head(), None);
let list: List<i32> = list.tail();
assert_eq!(list.head(), None);
let list: List<i32> = list.prepend(1).prepend(2).prepend(3);
let mut iter: Iter<'_, i32> = list.iter();
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&1));
}
}
双向链表
use std::cell::{Ref, RefCell, RefMut};
use std::rc::Rc;
/// 双向链表结构
pub struct List<T> {
head: Link<T>,
tail: Link<T>,
}
/// 链表节点包装
type Link<T> = Option<Rc<RefCell<Node<T>>>>;
/// 链表节点
pub struct Node<T> {
elem: T,
next: Link<T>,
prev: Link<T>,
}
/// 转换为迭代器
pub struct IntoIter<T>(List<T>);
/// 转换为迭代器引用
pub struct Iter<'a, T>(Option<Ref<'a, Node<T>>>);
/// 节点实现
impl<T> Node<T> {
/// 节点new函数
pub fn new(elem: T) -> Rc<RefCell<Self>> {
Rc::new(RefCell::new(Node {
elem,
next: None,
prev: None,
}))
}
}
/// 链表实现
impl<T> List<T> {
pub fn new() -> List<T>{
List { head: None, tail: None }
}
/// 转换为迭代器引用实现
pub fn iter(&self) -> Iter<T>{
// Iter 包装的类型为:Option<Ref<'a, Node<T>>>
Iter(self.head.as_ref().map(|head: &Rc<RefCell<Node<T>>>| head.borrow()))
}
/// 转换为迭代器实现
pub fn into_iter(self) -> IntoIter<T> {
IntoIter(self)
}
/// 从头插入节点
pub fn push_front(&mut self, elem: T) {
let new_head = Node::new(elem);
match self.head.take() {
// 如果头结点不为空
// 1:将头结点设置为None
// 2:将新建的节点置为头结点
// 3:将新头节点的next指向老节点
// 4:将老节点的prev置为新节点
Some(old_head) => {
// 非空链表,需要将新的节点和老的头部连接
// old_head的类型为 Rc<RefCell<Node<T>>> ,先调用RefCell的borrow_mut函数,将不可变引用转变为可变引用,才可以设置prev的值
old_head.borrow_mut().prev = Some(new_head.clone());
new_head.borrow_mut().next = Some(old_head);
self.head = Some(new_head);
}
None => {
// 如果头节点为空
// 1:设置新节点为头结点
// 2:将新节点的引用复制一个给tail
self.tail = Some(new_head.clone());
self.head = Some(new_head);
}
}
}
/// 尾插
pub fn push_back(&mut self, elem: T) {
let new_tail: Rc<RefCell<Node<T>>> = Node::new(elem);
match self.tail.take() {
Some(old_tail) => {
old_tail.borrow_mut().next = Some(new_tail.clone());
new_tail.borrow_mut().prev = Some(old_tail.clone());
self.tail = Some(new_tail);
},
None => {
self.head = Some(new_tail.clone());
self.tail = Some(new_tail);
}
}
}
/// 尾弹
pub fn pop_back(&mut self) -> Option<T> {
self.tail.take().map(|old_tail: Rc<RefCell<Node<T>>>| {
match old_tail.borrow_mut().next.take() {
Some(new_tail) => {
new_tail.borrow_mut().prev.take();
self.tail = Some(new_tail);
},
None => {
self.tail.take();
}
}
Rc::try_unwrap(old_tail).ok().unwrap().into_inner().elem
})
}
/// 从头弹出节点
pub fn pop_front(&mut self) -> Option<T> {
// 拿到头结点
self.head.take().map(|old_head: Rc<RefCell<Node<T>>>| {
// old_head为Rc<RefCell<Node<T>>>类型,通过borrow_mut()函数转为可变引用
// old_head的next置为空,并返回 old_head的next 的值
match old_head.borrow_mut().next.take() {
// 有值,类型为 Rc<RefCell<Node<T>>>
// 将 old_head的next 从命名为 new_head
Some(new_head) => {
// new_head 的 prev 指针置为none
new_head.borrow_mut().prev.take();
// 将链表的头结点置为new_head
self.head = Some(new_head);
}
// 如果头结点没有next,就说明当前节点为最后一个节点
// 所以讲尾指针置为None
None => {
self.tail.take();
}
}
// 返回old_head 里的值
// Rc::try_unwrap(): 如果 old_head 只有一个强引用,则返回内部的值
// 类型为 Result<RefCell<Node<T>>, Rc<RefCell<Node<T>>>>
// ok():将Result类型转换为 Options类型: Option<RefCell<Node<T>>>
// unwrap(): 拿到Option内的值,类型为:RefCell<Node<T>>
// into_inner(): 消耗RefCell 返回RefCell内包装的值:类型为Node<T>
// elem: 最后拿到Node内包装的值T,并返回被包装成Option<T>
Rc::try_unwrap(old_head).ok().unwrap().into_inner().elem
})
}
pub fn peek(&self) -> Option<Ref<T>> {
// self.head 的类型为 Option<Rc<RefCell<Node<T>>>>
self.head
// as_ref(): 将Option内的包装值转换为不可变引用 Option<&Rc<RefCell<Node<T>>>>
.as_ref()
// map():将包装内的值,类型为:&Rc<RefCell<Node<T>>> 映射为新值返回
.map(|node: &Rc<RefCell<Node<T>>>|
// 返回类型为Ref,所以用Ref::map包裹,函数含义为:将原Ref<T> 转换为 Ref<U> 后返回
// 原:node.borrow()的类型为:Ref<'_, Node<T>>
// fn:转换闭包:node类型 &Node<T> 要转换为 &T -> &node.elem
Ref::map(node.borrow(), |node: &Node<T>| &node.elem))
}
pub fn peek_back(&self) -> Option<Ref<T>> {
self.tail.as_ref().map(|node: &Rc<RefCell<Node<T>>> | {
Ref::map(node.borrow(), |node: &Node<T>| &node.elem)
})
}
pub fn peek_mut(&self) -> Option<RefMut<T>> {
self.head.as_ref().map(|node: &Rc<RefCell<Node<T>>>|
RefMut::map(node.borrow_mut(), |node: &mut Node<T>| &mut node.elem)
)
}
pub fn peek_back_mut(&self) -> Option<RefMut<T>> {
self.tail.as_ref().map(|node: &Rc<RefCell<Node<T>>>|
RefMut::map(node.borrow_mut(), |node: &mut Node<T>| &mut node.elem)
)
}
}
/// 转换迭代器实现,从前往后迭代
impl <T> Iterator for IntoIter<T>{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.0.pop_front()
}
}
/// 从后往前迭代
impl <T> DoubleEndedIterator for IntoIter<T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.0.pop_back()
}
}
/// 链表的Drop实现
impl<T> Drop for List<T> {
fn drop(&mut self) {
// self.pop_front().is_some() 判断是否有值
// self.pop_front()返回的类型为Option<T>
// 作用域为while循环体,完成一次循环体后,返回的Option<T>就会被自动Drop
while self.pop_front().is_some() {}
}
}
#[cfg(test)]
mod test {
use super::List;
#[test]
fn peek() {
let mut list: List<i32> = List::new();
assert!(list.peek().is_none());
assert!(list.peek_back().is_none());
assert!(list.peek_mut().is_none());
assert!(list.peek_back_mut().is_none());
list.push_front(1); list.push_front(2); list.push_front(3);
assert_eq!(&*list.peek().unwrap(), &3);
assert_eq!(&mut *list.peek_mut().unwrap(), &mut 3);
assert_eq!(&*list.peek_back().unwrap(), &1);
assert_eq!(&mut *list.peek_back_mut().unwrap(), &mut 1);
}
}

浙公网安备 33010602011771号