树的算法_1,并查集

11 篇文章 0 订阅
#include <stdio.h>

//节点个数
#define ELEM_C 10

//开始先假设每一个节点都是单独的一棵树,下标(节点)对应的值为它的父节点
//例如:节点0的根节点就是其本身:elems[0] == 0elems[4] == 4
int elems[ELEM_C] = {0,1,2,3,4,5,6,7,8,9};

//得到当前节点的根节点
int getRoot(int elem){
    if (elems[elem] == elem)
        return elem;
    else {
        //压缩路径,每次都在返回根节点前把elem的父节点改成根节点
        //这样以后就可以减少递归的深度,从而提高算法效率(其实直接return getRoot(elems[elem]);也可以,只不过递归的深度会越来越大)
        elems[elem] = getRoot(elems[elem]);
        return elems[elem];
    }
}

//分别求出两个节点的根,如果不是同一个根节点(即不属于同一个集合),则把其中一个根挂到另一个根下
void merge(int elem_1, int elem_2){
    int root_1 = getRoot(elem_1);
    int root_2 = getRoot(elem_2);
    if (root_1 != root_2)
        elems[root_2] = root_1;
}

void main() {
    int unionCount, u, v, i, sum=0;
    //输入节点之间的关联次数
    scanf("%d", &unionCount);
    for (i = 0; i < unionCount; ++i) {
        //合并树集合
        scanf("%d %d", &u, &v);
        merge(u, v);
    }

    //计算出一共有多少个集合
    for (i = 0; i < ELEM_C; ++i) {
        if (elems[i] == i)
            sum++;
    }

    printf("have %d set", sum);
}
测试如下:
9
1 2
3 4
5 2
4 6
2 6
8 7
9 7
1 6
2 4
have 3 set

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值