You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rust中实现O(1)克隆且可独立更新的集合?

实现O(1)时间克隆且支持独立新增的集合(Rust)

针对你需要的O(1)克隆、独立新增元素的需求,可以基于持久化数据结构的思路,结合Rc共享不变的底层数据,只在新增时维护独立的增量层。具体实现如下:

核心思路

利用分层结构:每个集合实例包含两部分

  • 一个Rc包裹的父集合(共享初始或之前的所有元素)
  • 一个独立的本地集合,存储当前实例新增的元素

因为元素仅新增、不删除修改,父集合可以安全共享,克隆时只需创建一个指向原集合的Rc实例,同时初始化空的本地增量集合,这一步是O(1)时间复杂度。新增元素时,只在当前实例的本地集合中添加,不会影响共享的父集合。

Rust代码实现

use std::collections::HashSet;
use std::rc::Rc;

#[derive(Clone)]
enum PersistentSet<T: Eq + std::hash::Hash + Clone> {
    // 根节点,无父集合,仅存储自身元素
    Root(HashSet<T>),
    // 子节点,包含共享的父集合和本地新增元素
    Node {
        parent: Rc<PersistentSet<T>>,
        local: HashSet<T>,
    },
}

impl<T: Eq + std::hash::Hash + Clone> PersistentSet<T> {
    // 从初始元素创建根集合
    fn new(elements: impl IntoIterator<Item = T>) -> Self {
        PersistentSet::Root(elements.into_iter().collect())
    }

    // 插入元素:仅在本地集合中添加(如果父链中不存在该元素)
    fn insert(&mut self, value: T) -> bool {
        if self.contains(&value) {
            return false;
        }

        match self {
            PersistentSet::Root(set) => set.insert(value),
            PersistentSet::Node { local, .. } => local.insert(value),
        }
    }

    // 检查元素是否存在:遍历本地集合 + 所有父集合
    fn contains(&self, value: &T) -> bool {
        match self {
            PersistentSet::Root(set) => set.contains(value),
            PersistentSet::Node { parent, local } => {
                local.contains(value) || parent.contains(value)
            }
        }
    }

    // 遍历所有元素:本地元素 + 父链元素
    fn iter(&self) -> impl Iterator<Item = &T> {
        match self {
            PersistentSet::Root(set) => set.iter(),
            PersistentSet::Node { parent, local } => {
                local.iter().chain(parent.iter())
            }
        }
    }
}

fn main() {
    // 创建初始集合set1
    let mut set1 = PersistentSet::new([1, 2, 3, 4, 5]);
    // O(1)时间克隆得到set2
    let mut set2 = set1.clone();

    // 分别独立新增元素
    set1.insert(10);
    set2.insert(6);

    // 输出set1的元素:{1,2,3,4,5,10}
    println!("set1 elements: {:?}", set1.iter().collect::<Vec<_>>());
    // 输出set2的元素:{1,2,3,4,5,6}
    println!("set2 elements: {:?}", set2.iter().collect::<Vec<_>>());
}

关键说明

  • O(1)克隆:PersistentSet的Clone实现依赖Rc的克隆(原子引用计数操作,O(1))和空HashSet的创建,整体时间复杂度为O(1)。
  • 独立更新:新增元素时仅操作当前实例的local集合,不会修改共享的父集合,因此不同实例的更新完全独立。
  • 元素查询:查询时需要遍历当前实例的本地集合和所有父集合,时间复杂度为O(k)(k为分层次数),但在仅新增的场景下,分层次数远小于元素总数,实际效率接近O(1)。

内容的提问来源于stack exchange,提问作者Theodora

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:25:17