算法-并查集-C

记录算法使用场景和算法实现

使用场景

将问题抽象为算法里的图,并查集算法可以根据结点之前关系连通和判断是否连通。

代码实现

c 复制代码
typedef struct UnionFind {
    // 记录连通分量的个数
    int count;
    int *parent;
    int *size;
    int (*find)(struct UnionFind *, int);
    void (*munion)(struct UnionFind *, int, int);
    bool (*isConnet)(struct UnionFind *, int, int);
} UnionFind;
void UFFree(UnionFind *obj) {
    free(obj->parent);
    free(obj->size);
    free(obj);
    return;
}
int UFFind(UnionFind *obj, int x) {
    while (obj->parent[x] != x) {
        // 路径压缩
        obj->parent[x] = obj->parent[obj->parent[x]];
        x = obj->parent[x];
    }
    return x;
}
void UFUnion(UnionFind *obj, int x, int y) {
    int rootX = UFFind(obj, x);
    int rootY = UFFind(obj, y);
    if(rootX == rootY) return;
    if(obj->size[rootX] > obj->size[rootY]) {
        obj->parent[rootY] = rootX;
        obj->size[rootX] += obj->size[rootY];
    }
    else {
        obj->parent[rootX] = rootY;
        obj->size[rootY] += obj->size[rootX];
    }
    obj->count--;
}
bool IsUFConnet(UnionFind *obj, int x, int y) {
    return UFFind(obj, x) == UFFind(obj, y);
}
UnionFind *UFInit(int n) {
    UnionFind *obj = (UnionFind *)malloc(sizeof(UnionFind));
    obj->count = n;
    obj->parent = (int *)malloc(sizeof(int)*n);
    obj->size = (int *)malloc(sizeof(int)*n);
    for(int i=0; i<n; i++) {
        obj->parent[i] = i;
        obj->size[i] = 1;
    }
    obj->find = UFFind;
    obj->isConnet = IsUFConnet;
    obj->munion = UFUnion;
    return obj;
}

示例

leetcode-130. 被围绕的区域

题目浅析:矩形区域中填充'X'和'O',除矩形四边上为'O'及联通的'O'外,其余区域全变成'X'。

c 复制代码
void solve(char** board, int boardSize, int* boardColSize) {
    int m = boardSize;
    int n = boardColSize[0];
    UnionFind *obj = UFInit(m*n+1);
    for(int i=0; i<m; i++) {
        if(board[i][0] == 'O') {
            obj->munion(obj, m*n, i*n);
        }
        if(board[i][n-1] == 'O') {
            obj->munion(obj, m*n, i*n+n-1);
        }
    }
    for(int j=0; j<n; j++) {
        if(board[0][j] == 'O') {
            obj->munion(obj, m*n, j);
        }
        if(board[m-1][j] == 'O') {
            obj->munion(obj, m*n, (m-1)*n+j);
        }
    }
    int dir[4][2] = {{0,-1}, {0,1}, {1,0}, {-1,0}};
    for(int i=1; i<m-1; i++) {
        for(int j=1; j<n-1; j++) {
            if(board[i][j] == 'O') {
                for(int k=0; k<4; k++) {
                    int ni = i+dir[k][0];
                    int nj = j+dir[k][1];
                    if(board[ni][nj] == 'O') {
                        obj->munion(obj, ni*n+nj, i*n+j);
                    }
                }
            }
        }
    }
    for(int i=1; i<m-1; i++) {
        for(int j=1; j<n-1; j++) {
            if(!obj->isConnet(obj, m*n, i*n+j)) {
                board[i][j] = 'X';
            }  
        }   
    }
    return;
}
相关推荐
努力学算法的蒟蒻2 小时前
day47(12.28)——leetcode面试经典150
算法·leetcode·面试
熊猫钓鱼>_>2 小时前
基于Trae/Whisper/FFmpeg与Knowledge Graph MCP技术开发语音生成会议纪要智能应用
开发语言·人工智能·python·深度学习·ffmpeg·whisper·trae
byzh_rc2 小时前
[算法设计与分析-从入门到入土] 复杂算法
数据库·人工智能·算法·机器学习·支持向量机
七夜zippoe2 小时前
Python迭代器与生成器深度解析:从原理到协程应用实战
开发语言·python
Sunsets_Red2 小时前
待修改莫队与普通莫队优化
java·c++·python·学习·算法·数学建模·c#
葡萄城技术团队2 小时前
在 Java 中优化 MySQL 查询以提升性能
java·开发语言·mysql
Rhys..2 小时前
js-箭头函数
开发语言·javascript·ecmascript
爱学习的梵高先生2 小时前
C++:友元
开发语言·c++
资深低代码开发平台专家2 小时前
厌倦JavaScript 框架桎梏?Still.js:用原生之力,解遗留系统之困
开发语言·javascript·ecmascript