并查集

半世苍凉 提交于 2020-02-16 23:32:08

并查集

  • 集合的运算:交、并、补、差和判断一个元素是否属于某一集合。
  • 并查集:集合的合并、判断一个元素是否属于某一集合的操作。

并查集问题中集合如何存储

  • 可以用树结构表示集合,每棵树代表一个集合,树的每个节点一个集合的元素。例:
    树

  • 怎么更加方便的表示一棵树?答案是用数组。数组元素类型如下:

    Typedef struct SetNode{
        ElementType Data;//存储数据
        int Parent;//存储父节点在数组中的下标;如果本身就是父节点,就用负数表示,负数绝对值的大小可以用来确定这棵树的高度
    }SetType;
    

    例:
    数组
    表示的集合为:
    集合

实现

  1. 查找一个元素在哪个集合

    int Find( SetType S[ ], ElementType X )
     {   /* 在数组S中查找值为X的元素所属的集合 */
         /* MaxSize是全局变量,为数组S的最大长度 */
         int i;
    
         for ( i=0; i < MaxSize && S[i].Data != X; i++) ;
         if( i >= MaxSize ) return -1; /* 未找到X,返回-1 */
    
         for( ; S[i].Parent > 0; i = S[i].Parent ) ;
         return i; /* 找到X所属集合,返回树根结点在数组S中的下标 */
     }
    
  2. 集合的合并

    void Union( SetType S[ ], ElementType X1, ElementType X2 )
     {
         int Root1, Root2;
         Root1 = Find(S, X1);
         Root2 = Find(S, X2);
    
         /* 合并时为了让树的左右子树高度差别不大,只要将高度小的加入高度大的即可 */
         if(Root1 != Root2)
         {
             if(S[Roo1].Parent > S[Root2].Parent)
             {
                 S[Roo1].Parent = Root2;
             }
             else if(S[Roo1].Parent < S[Root2].Parent)
             {
                 S[Roo2].Parent = Root1;
             }
             else
             {
                 S[Roo2].Parent = Root1;
                 S[Roo1].Parent--;
             }
         }
     }
    
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!