Skip to content

Vec

Vec 是一种强大但简单的数据容器,它提供了数据收集机制和各种各样的操作,这也是我们反复将其作为实现其他底层数据结构的原因。Vec 类似于 Python 中的 List,使用起来非常方便。然而,不是所有的编程语言都包括 Vec,或者说不是所有的数据类型都适合使用 Vec。

Vec 是用一组链表节点来构建的,其中的每个节点可以通过显式引用链接到下一个节点。只要知道在哪里找到第一个节点,之后的每一个节点就可以通过连续获取下一个链接来找到。

考虑到引用在 Vec 中的作用,Vec 必须保持对第一个节点的引用,None 表示链表不引用任何内容。链表的头节点表示链表中的第一个节点,其中保存了下一个节点的地址。注意,Vec 本身不包含任何节点对象,而是仅包含对链表结构中第一个节点的引用。

链表结构只提供了一个入口,即链表头部。所有其他节点只能通过访问第一个节点,然后跟随下一个链接到达。这意味着添加新节点的最高效方式就是在链表的头部添加,换句话说,将新项作为链表的第一项,并将现有项链接到新项的后面。

此处实现的 Vec 是无序的,若要实现有序 ( 包括全序和偏序 ) 的 Vec,请添加数据比较函数。下面的 LVec 只实现了 Vec 标准库中的部分功能,print_lvec() 用于输出 LVec 中的数据项。

rust
use std::fmt::Debug;

// 节点
#[derive(Debug)]
struct Node<T> {
    elem: T,
    next: Link<T>,
}

type Link<T> = Option<Box<Node<T>>>;

impl<T> Node<T> {
    fn new(elem: T) -> Self {
        Self { elem, next: None }
    }
}

// 链表 Vec
#[derive(Debug)]
struct LVec<T> {
    size: usize,
    head: Link<T>,
}

impl<T: Copy + Debug> LVec<T> {
    fn new() -> Self {
        Self {
            size: 0,
            head: None,
        }
    }

    fn is_empty(&self) -> bool {
        0 == self.size
    }

    fn len(&self) -> usize {
        self.size
    }

    fn clear(&mut self) {
        self.size = 0;
        self.head = None;
    }

    fn push(&mut self, elem: T) {
        let node = Node::new(elem);

        if self.is_empty() {
            self.head = Some(Box::new(node));
        } else {
            let mut curr = self.head.as_mut().unwrap();

            // 找到链表中的最后一节节点
            for _i in 0..self.size - 1 {
                curr = curr.next.as_mut().unwrap();
            }

            // 在最后一个节点的后面插入新的数据
            curr.next = Some(Box::new(node));
        }

        self.size += 1;
    }

    // 在栈尾添加新的 LVec
    fn append(&mut self, other: &mut Self) {
        while let Some(node) = other.head.as_mut().take() {
            self.push(node.elem);
            other.head = node.next.take();
        }

        other.clear();
    }

    fn insert(&mut self, mut index: usize, elem: T) {
        if index >= self.size {
            index = self.size;
        }

        // 分三种情况插入新节点
        let mut node = Node::new(elem);
        if self.is_empty() {
            // LVec 为空
            self.head = Some(Box::new(node));
        } else if index == 0 {
            // 在链表的头部插入
            node.next = self.head.take();
            self.head = Some(Box::new(node));
        } else {
            // 在链表的中间插入
            let mut curr = self.head.as_mut().unwrap();
            for _i in 0..index - 1 {
                // 找到插入位置
                curr = curr.next.as_mut().unwrap();
            }
            node.next = curr.next.take();
            curr.next = Some(Box::new(node));
        }

        self.size += 1;
    }

    fn pop(&mut self) -> Option<T> {
        if self.size < 1 {
            None
        } else {
            self.remove(self.size - 1)
        }
    }

    fn remove(&mut self, index: usize) -> Option<T> {
        if index >= self.size {
            return None;
        }

        // 分两种情况删除节点,头节点的删除最好处理
        let mut node;
        if 0 == index {
            node = self.head.take().unwrap();
            self.head = node.next.take();
        } else {
            // 对于其他节点,找到待删除节点并处理前后链接
            let mut curr = self.head.as_mut().unwrap();
            for _i in 0..index - 1 {
                curr = curr.next.as_mut().unwrap();
            }
            node = curr.next.take().unwrap();
            curr.next = node.next.take();
        }

        self.size -= 1;

        Some(node.elem)
    }

    // 以下是为栈实现的迭代功能
    // into_iter: 栈改变,成为迭代器
    // iter: 栈不变,只得到不可变迭代器
    // iter_mut: 栈不变,得到可变迭代器
    fn into_iter(self) -> IntoIter<T> {
        IntoIter(self)
    }

    fn iter(&self) -> Iter<T> {
        Iter {
            next: self.head.as_deref(),
        }
    }

    fn iter_mut(&mut self) -> IterMut<T> {
        IterMut {
            next: self.head.as_deref_mut(),
        }
    }

    // 输出 LVec 中的数据项
    fn print_lvec(&self) {
        if 0 == self.size {
            println!("Empty lvec");
        }

        for item in self.iter() {
            println!("{:?}", item)
        }
    }
}

// 实现三种迭代功能
struct IntoIter<T: Copy + Debug>(LVec<T>);
impl<T: Copy + Debug> Iterator for IntoIter<T> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        self.0.pop()
    }
}

struct Iter<'a, T: 'a> {
    next: Option<&'a Node<T>>,
}
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
        })
    }
}

struct IterMut<'a, T: 'a> {
    next: Option<&'a mut Node<T>>,
}
impl<'a, T> Iterator for IterMut<'a, T> {
    type Item = &'a mut T;
    fn next(&mut self) -> Option<Self::Item> {
        self.next.take().map(|node| {
            self.next = node.next.as_deref_mut();
            &mut node.elem
        })
    }
}

fn main() {
    basic();
    iter();

    fn basic() {
        let mut lvec1: LVec<i32> = LVec::new();
        lvec1.push(10);
        lvec1.push(11);
        lvec1.push(12);
        lvec1.push(13);
        lvec1.insert(0, 9);

        lvec1.print_lvec();

        let mut lvec2: LVec<i32> = LVec::new();
        lvec2.insert(0, 8);
        lvec2.append(&mut lvec1);

        println!("len: {}", lvec2.len());
        println!("pop: {:?}", lvec2.pop().unwrap());
        println!("remove: {:?}", lvec2.remove(0).unwrap());

        lvec2.print_lvec();
        lvec2.clear();
        lvec2.print_lvec();
    }

    fn iter() {
        let mut lvec: LVec<i32> = LVec::new();
        lvec.push(10);
        lvec.push(11);
        lvec.push(12);
        lvec.push(13);

        let sum1 = lvec.iter().sum::<i32>();
        let mut addend = 0;
        for item in lvec.iter_mut() {
            *item += 1;
            addend += 1;
        }

        let sum2 = lvec.iter().sum::<i32>();
        println!("{sum1} + {addend} = {sum2}");

        assert_eq!(50, lvec.into_iter().sum::<i32>());
    }
}

output:

shell
9
10
11
12
13
len: 6
pop: 13
remove: 8
9
10
11
12
Empty lvec
46 + 4 = 50