ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Rust——并查集

2021-07-15 13:02:06  阅读:163  来源: 互联网

标签:parent union self 查集 usize root find Rust


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

标签:parent,union,self,查集,usize,root,find,Rust
来源: https://blog.csdn.net/comien/article/details/118756985

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有