并查集的简单实现(c/c++)

并查集的简单实现与相关例子展示

  1. 初始化,初始化并查集
  2. 合并集合,合并两个节点所在的集合
  3. 查找节点所在集合,查找某一个节点归属哪一个集合
  4. 相关应用,商品分类,将并查集运用于商品分类管理中
  5. #include <iostream>
    
    const int M=1000;//定义并查集的最大容量
    int pre[M];//用于储存节点的前驱
    int high[M];//用于储存节点的高度
    
    bool initialize(int n);//初始化函数,用于对并查集进行初始化,返回bool类型
    
    int find_p(int n);//查找函数(运用了路径压缩)
    
    bool judge(int a, int b);//判断函数,判断两个节点是否属于同一集合的函数
    
    int merge(int a, int b);//合并函数,用于合并两个集合
    
    void yuansu(int n[], int h[]);//应用模块初始化函数,用于导入应用数据
    
    void prin(int i);//应用模块输出函数,用于输出商品所属的类
    
    int main()//程序主函数
    {
        printf("欢迎使用并查集演示程序!\n");
        int n, i , c=1;
        int f, a, b;
        printf("请输入集合的节点数目:");
        scanf("%d", &n);
        if (initialize(n))//初始化,选择初始化的容量大小
        {
                printf("初始化成功!\n");
        }
        else
        {
                printf("初始化失败!\n");
        }
        system("pause");//按任意键继续
        system("cls");//清屏函数
        while (c == 1)//循环,如果不主动选择退出会一直重复菜单
        {
            int fu;//定义一个变量来操作菜单
            printf("*                    功能面板                   *\n");
            printf("*______________________________________________*\n");
            printf("*              1.查找单个节点的根节点                   \n");
            printf("*          2.查看两个节点是否属于同一集合           \n");
            printf("*             3.合并两个节点所在的集合           \n");
            printf("*                     4.退出                        \n");
            printf("*______________________________________________*\n");
            printf("请输入要进行的操作:");
            scanf("%d", &fu);
            switch (fu)//运用switch函数来实现对不同功能的控制
            {
            case 1://查找功能,调用查找函数
                printf("请输入要查找的节点:");
                scanf("%d", &f);
                i = find_p(f);
                printf("该节点的根节点为:%d\n", f);
                break;
            case 2://查找两个节点是否属于同一个集合的功能,调用判断函数
                printf("请输入要查找的两个节点:\n");
                scanf("%d %d", &a, &b);
                if (judge(a, b))
                {
                    printf("根节点一致!\n");
                }
                else
                {
                    printf("根节点不一致!\n");
                }
                break;
            case 3://合并集合功能,调用合并函数
                printf("请输入要合并的两个节点:\n");
                scanf("%d %d", &a, &b);
                if (merge(a, b))
                {
                    printf("合并成功!\n");
                }
                else
                {
                    printf("合并失败!\n");
                }
                break;
            case 4://输入4结束程序
                c = 0;
                break;
            }
            system("pause");//按任意键继续
            system("cls");//清屏函数
        }
        c = 1;
        initialize(100);//对并查集进行初始化
        yuansu(pre,high);
        while (c == 1)//和上述菜单一样的循环操作,需要输入4才会停止
        {
            int fu;
            printf("*                应用:商品分类                   *\n");
            printf("*______________________________________________*\n");
            printf("*       1.查找第n号商品属于哪一类(n>0&&n<=100)          \n");
            printf("*           2.查看两个商品是否属于同一类            \n");
            printf("*             3.合并两个商品所在的类                 \n");
            printf("*                     4.退出                        \n");
            printf("*______________________________________________*\n");
            printf("请输入要进行的操作:");
            scanf("%d", &fu);
            switch (fu)
            {
            case 1://查找功能,调用查找函数和输出函数
                printf("请输入要查找的商品的序号:");
                scanf("%d", &f);
                i = find_p(f);
                prin(i);
                break;
            case 2://调用判断函数
                printf("请输入要查找的两件商品的序号:\n");
                scanf("%d %d", &a, &b);
                if (judge(a, b)){
                    printf("两件商品属于同一类!\n");
                }
                else
                {
                    printf("两件商品不属于同一类!\n");
                }
                break;
            case 3://调用合并函数
                printf("请输入要合并的两个类中的任意两件商品:\n");
                scanf("%d %d", &a, &b);
                if (merge(a, b))
                {
                    printf("合并成功!\n");
                }
                else
                {
                    printf("合并失败!\n");
                }
                break;
            case 4://退出
                c = 0;
                break;
            }
            system("pause");//按任意键继续
            system("cls");//清屏函数
        }
        return 0;
    }
    
    bool initialize(int n)//初始化函数,用于对并查集进行初始化,返回bool类型
    {
        int i;
        for (i = 0; i < n; i++)//对每个节点进行初始化,每个节点的上级都是自己
        {
            pre[i] = i;
            high[i] = 1;
        }
        if (pre[i - 1] == i - 1 && high[i - 1] == 1)//判断是否初始化成功,并返回一个bool类型
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    int find_p(int n)//查找函数(运用了路径压缩)
    {
        if (pre[n] == n)//递归结束条件,该节点的上级为自己,也就是找到了该集合的代表节点
        {
            return n;//返回代表节点的序号
        }
        return pre[n] = find_p(pre[n]);//递归查找节点的上级,并进行优化,使节点的上级指向该集合的代表节点
    }
    
    bool judge(int a, int b)//判断函数,判断两个节点是否属于同一集合的函数
    {
        if (find_p(a) == find_p(b))//调用查找函数,查看两个节点所属集合的代表节点是否相同
        {
            return true;//相同,则返回true
        }
        else
        {
            return false;//不相同。则返回false
        }
    }
    
    int merge(int a, int b)//合并函数,用于合并两个集合
    {
        a = find_p(a);//查找a所在集合的代表节点
        b = find_p(b);//查找b所在集合的代表节点
        if (a == b)//判断a和b是否属于同一个集合
        {
            return 0;//如果a和b相同,则a,b属于同一个集合,不需要合并,直接返回false
        }
        if (high[a] > high[b])//比较两个集合的高度,尽可能的使合并后的集合简洁
        {
            pre[b] = a;
        }
        else
        {
            pre[a] = b;
        }
        return 1;
    }
    
    void yuansu(int n[], int h[])//应用模块初始化函数,用于导入应用数据
    {
        int i, j = 1;
        for (i = 1; i <= 100; i++)//这里先默认让10个商品为一类
        {
            n[i] = j;
            if (i % 10 == 0)//每十个商品以第一个商品为代表
            {
                j += 10;
            }
        }
    }
    
    void prin(int i)//应用模块输出函数,用于输出商品所属的类
    {
        int k = 0;
        while (i != 0)//计算该商品属于第几类
        {
            k = k + i % 10;
            i /= 10;
        }
        printf("该商品属于第%d类。\n", k);
    }

     

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YoloMari

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值