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);
    }

}
posted @ 2023-08-21 00:08  ylc0x01  阅读(129)  评论(0)    收藏  举报