算法-并查集-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;
}
相关推荐
揽星河..8 分钟前
【C语言】扫雷游戏
c语言·算法·游戏
丘山录13 分钟前
本地部署 LongCat-2.5,要 7 台机器我只有 4 台
人工智能·算法
Allen_LVyingbo18 分钟前
NVIDIA CUDA Tile 在医疗计算中的算子形式化、算法重构与内核实现
大数据·python·算法·重构·知识图谱·健康医疗·数据库架构
云和数据.ChenGuang32 分钟前
Python 闭包详解:从原理到实战
linux·开发语言·人工智能·python·kubernetes
揣一尾游鱼yu40 分钟前
内部类和Object笔记
java·开发语言·object·内部类
小鱼仙官1 小时前
Qt 主界面弹出分界面
开发语言·qt
你怎么知道我是队长1 小时前
C++零基础第3周:if/else、switch、for/while/do-while 控制流完全指南(附20段可运行代码+避坑清单)
java·开发语言·c++
冻柠檬飞冰走茶2 小时前
PTA刷题集之Airline Routes(C语言实现)
c语言·开发语言·数据结构·算法
宗旨飞翔2 小时前
不同的二叉搜索树
算法
damoluomu2 小时前
Node 的 Headless 出厂没有前台,Java 的 Headless 是从门户里长出来的
java·开发语言·node.js