【数据结构】 C++实现并查集 (Disjoint Set Union)

// 对应leetcode题目:剑指 Offer II 118. 多余的边
并查集的作用:检查无向图中是否存在环
实现方式:用树来表示集合,并以数组的方式建树,通过查找一个边的两个顶点的根节点的关系判断是否存在环,
若不同,则说明这两个集合是可以通过当前当前的边建立起联系的,即他们属于同一个集合,这时将两棵树合并(暂时简单的将一个根节点挂在另一个根节点下面);
若相同:则说明这两个点在同一个集合内,说明存在了环!

C++的naive实现:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Solution{
    
    
public:
    vector<int> ans;
    int get_parent(vector<int>& parent, int pos) {
    
          // 若节点无父节点,返回-1
        int ret = pos;
        while(parent[ret] != -1) {
    
    
            ret = parent[ret];
        }

        return ret;

    }
    bool insert(vector<int>& parent, int a, int b) {
    
    
        int p_a = get_parent(parent, a);
        int p_b = get_parent(parent, b);
        if(p_a == p_b) {
    
    
            this->ans = {
    
    a, b};
            return false;
        }
        else       // union
            parent[p_a] = p_b;      // a接在b下面
        
        return true;
    }

    vector<int> check_circle(vector<vector<int>>& edges) 
    {
    
    
        int n = edges.size();
        vector<int> parent(n, -1);
        for(int i=0; i<n; i++) {
    
    
            insert(parent, edges[i][0], edges[i][1]);
        }

        return ans;
    }
};

int main()
{
    
    
    // 通过 删掉一个边形树(无环图)。若有多种删除方法, 则按照在edges中出现的顺序,返回最后出现的
    vector<vector<int>> edges = {
    
    {
    
    0, 1}, {
    
    1, 2}, {
    
    3, 4}, {
    
    2, 4}, {
    
    1, 3}, {
    
    2, 5}};
    Solution base;
    vector<int> ans = base.check_circle(edges);


    return 0;
}

猜你喜欢

转载自blog.csdn.net/ayitime/article/details/126677458