Rust——并查集

本文介绍了如何使用Rust编程语言实现并查集数据结构,包括`is_connected`、`union_elements`和`get_size`方法,通过示例展示了如何创建、查询和操作集合。

Rust——并查集

实现

#![allow(unused)]
//! 并查集:解决节点连接/关联问题

/// 并查集 trait
trait UF {
    fn is_connected(&mut self, p: usize, q: usize) -> bool;
    fn union_elements(&mut self, p: usize, q: usize);
    fn get_size(&self) -> usize;
}

/// 并查集结构
pub struct UnionFind {
    // 存储父节点
    parent: Vec<usize>,
    // 高度
    rank: Vec<usize>,
}

impl UnionFind {
    /// 构造
    pub fn new_with_size(size: usize) -> Self {
        let mut res = Self {
            parent: vec![0_usize; size],
            rank: vec![1_usize; size],
        };
        // 为每个元素分组
        for i in 0..res.parent.len() {
            res.parent[i] = i;
        }
        return res;
    }

    /// 查询p的根
    fn find(&mut self, p: usize) -> Result<usize, &'static str> {
        if p >= self.parent.len() {
            return Err("参数错误");
        }
        let mut c = p;
        // 寻找根
        while c != self.parent[c] {
            // 压缩高度
            self.parent[c] = self.parent[self.parent[c]];
            c = self.parent[c];
        }
        return Ok(c);
    }
}

impl UF for UnionFind {
    /// 查看两元素是不是同一个根
    fn is_connected(&mut self, p: usize, q: usize) -> bool {
        let p_root = self.find(p).unwrap();
        let q_root = self.find(q).unwrap();
        return p_root == q_root;
    }

    /// 合并两个元素为一个根
    fn union_elements(&mut self, p: usize, q: usize) {
        let p_root = self.find(p).unwrap();
        let q_root = self.find(q).unwrap();
        if p_root != q_root {
            if self.rank[p_root] < self.rank[q_root] {
                self.parent[p_root] = self.parent[q_root];
            } else if self.rank[q_root] < self.rank[p_root] {
                self.parent[q_root] = self.parent[p_root];
            } else {
                self.parent[q_root] = self.parent[p_root];
                self.rank[p_root] += 1;
            }
        }
    }

    fn get_size(&self) -> usize {
        return self.parent.len();
    }
}


#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        let mut union_find = UnionFind::new_with_size(10);
        union_find.union_elements(3, 5);
        union_find.union_elements(2, 1);
        union_find.union_elements(5, 1);
        union_find.union_elements(5, 4);
        assert_eq!(union_find.is_connected(4, 1), true);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值