<数据结构>并查集与树

作用

查:给定一个元素,查询它在哪个集合内
并:合并两个元素所在的集合

实现思路

对应关系#

元素-->结点
集合-->树
多个集合-->森林

用树的根节点作为不同树的标志
合并时只需要将根节点链接

实现#

用数组表示树,数组下标表示元素值,数组的值表示该元素对应的父亲结点
father[i] = j : 元素i的父亲结点是j
对于根节点 father[i] = i


图中有两个集合,由两个树表示,根节点分别为元素2,3

查找元素4:

合并元素4,0所在集合:

代码#

#include<stdio.h>
const int maxn = 10;
int father[maxn];

void init(int n){  //初始化,开始时,所有元素都不在同一个集合,自身构成集合
    for(int i = 0; i < n; i++)
        father[i] = i;
}

int find(int x){  //查找元素x所在的集合的根节点
    while(x != father[x])
        x = father[x];
    return x;
}
void Union(int x1, int x2){ //合并x1和x2所在的集合
    int Fax1, Fax2;  //分别寻找x1,x2的根节点
    Fax1 = find(x1);
    Fax2 = find(x2);
    if(Fax1 != Fax2)  //如果x1,x2不在同一个集合,合并
        father[Fax1] = Fax2;
}

改进:路径压缩

有时路径过长会导致find函数内部的while循环要执行很多次才能找到根节点

查找0时需要执行多次while循环

对find函数进行改进

int find(int x){
    int a = x;
    while(x != father[x])
        x = father[x];
    //路径压缩
    while(a != father[a]){
        father[a] = x;
        a = father[a];
    }
    return x;
}

压缩后:

posted @   咪啪魔女  阅读(67)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示