zoukankan      html  css  js  c++  java
  • 并查集的理解

    从数学的角度来说,假设我们有n个集合{{..},{..},.......},而每个集合内又有众多的元素{A,B,C.....},{1,2,3,4......}等等,每个集合的元素都存在这或多或少的联系,什么联系不清楚,但我们只需知道存在这样的关系即可;而突然,我们希望让集合之间也联系起来,而又不想一个一个的将它们绑到一起,那么,并查集就是解决它们之间联系的数据结构。树就是我们需要用到的一种连接结构。

    并查集一般包含三个主体:

    1. makeSet();建立一个数组并储存每一个数的节点(可以看成他们所处在的队伍的编号);

       for(int i=1;i<=n;i++)
            per[i] = i;

    2.Find(int  x);查找x的根节点,也就是x所队伍的代表人(代表人特征 :Find(n)=n);

        int find(int p)  
        {  
            while(p != id[p])  
                {  
                      p = id[p];  
                }  
            return p;  
        }        
    •  在这里我们简单的思考一下Find的效率问题,我们通过不断个根节点添加子节点的方式(也就是树),将两者联系在一起,如果树的路径变得很长,就需要从下到上一直访问下去,效率就大大降低,因此我们需要想个办法决绝路径过长的问题;
    • 路径压缩:所有的子节点,还是子子节点,全部直接连接到根节点上去;
          • int Find(int x)
            {
                if(per[x]!=x)
                    per[x] = Find(per[x]);//把属于一个队伍的人全部和老大联系起来;
                return per[x];
            }

     3.unionSet(int x,int y) :将两个关联的点连接起来;

                  void Union(int a,int b)
                  {
                      //if(Find(a)!=Find(b))
                         //per[Find(a)]=b;
                int ax = Find(a);
                int bx = Find(b);
                if(ax!=bx)
                  per[ax]=b;
            }

      在这里,我们考虑下per[ax] = b,为甚么一定是这样的,而不是per[bx] = a呢?是不是很奇怪;其实无论哪种都没有错,都可以将两者联系;但我们思考一下,如果总是固定的一个添加方法,如果出现子树远远大于根数,那么连接起来的情况就会很离奇。树的路径就会变得很大,因此我们自然会想到,那就把小的连接到大的不就好了;而Find()方法的效率取决于树的路径大小,那么我们不就又提高了代码的效率了吗?

    void unionSet(int p, int q)  
    {  
        int i = find(p);  
        int j = find(q);  
        if (i == j) return;  
        if (sz[i] < sz[j])//sz[]用来记录树的size;
             { id[i] = j; sz[j] += sz[i]; }  
        else 
            { id[j] = i; sz[i] += sz[j]; }  
        count--;  
    }  
  • 相关阅读:
    换行的展示
    jsp页面的导出功能
    怎么设置回车键为提交功能?
    HBuilder使用心得
    js和jQuery
    前端常用技术总结--java程序员
    对压缩文件加密
    删除表中一个字段的SQL语句
    用NPOI操作EXCEL-锁定列CreateFreezePane()
    MVC 点击下载文档
  • 原文地址:https://www.cnblogs.com/7750-13/p/7263836.html
Copyright © 2011-2022 走看看