算法-并查集-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;
}
相关推荐
chase。几秒前
Python包构建工具完全指南:python -m build 使用详解
开发语言·chrome·python
SuperEugene4 分钟前
前端 utils 工具函数规范:拆分 / 命名 / 复用全指南,避开全局污染等高频坑|编码语法规范篇
开发语言·前端·javascript
A923A10 分钟前
【洛谷刷题 | 第四天】
算法·前缀和·贪心·洛谷·差分
古城小栈13 分钟前
Go 底层代码的完整分类
开发语言·后端·golang
耳冉鹅17 分钟前
Go无锁共享内存环形缓冲区设计
开发语言·golang
bai_lan_ya23 分钟前
使用linux的io文件操作综合实验_处理表格
linux·服务器·算法
计算机安禾27 分钟前
【C语言程序设计】第36篇:二进制文件的读写
c语言·开发语言·c++·算法·github·visual studio code·visual studio
ZPC821028 分钟前
OLOv11 + 深度相机的方案实现高精度3D定位
人工智能·数码相机·算法·机器人
子非鱼@Itfuture29 分钟前
try-catch和try-with-resources区别是什么?try{}catch(){}和try(){}catch(){}有什么好处?
java·开发语言
_日拱一卒32 分钟前
LeetCode:字母异位词分组
算法·leetcode·职场和发展