算法-并查集-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;
}
相关推荐
小白学大数据1 分钟前
深度探索:Python 爬虫实现豆瓣音乐全站采集
开发语言·爬虫·python·数据分析
Xin_ye100864 分钟前
C# 零基础到精通教程 - 第八章:面向对象编程(进阶)——继承与多态
开发语言·c#
数智工坊8 分钟前
【UniT论文阅读】:用统一物理语言打通人类与人形机器人的知识壁垒
论文阅读·人工智能·深度学习·算法·机器人
m0_748839499 分钟前
R包grafify:简单操作实现高效统计绘图
开发语言·r语言
梓䈑10 分钟前
【算法题攻略】模拟
c++·算法
Evand J13 分钟前
【课题推荐与代码介绍】卡尔曼滤波器正反向估计算法原理与MATLAB实现
开发语言·算法·matlab
奋斗的小方15 分钟前
Java基础篇09:项目实战
java·开发语言
DFT计算杂谈16 分钟前
VASP新手入门: IVDW 色散修正参数
linux·运维·服务器·python·算法
froginwe1128 分钟前
Vue.js 监听属性
开发语言
c++逐梦人30 分钟前
五种IO模型与⾮阻塞IO
开发语言·网络