zoukankan      html  css  js  c++  java
  • 数据结构-并查集

    适合需要反复用到查询某个元素归属于哪个集合的运算

    初始化时每个元素自成为单元素集合,parent均为-1。此后parent[x]>0时表示元素x的父在数组中的下标parent[x]<0时表示以元素x为根的集合的元素个数

    Find操作可以查询元素归属哪个集合搜索并返回包含元素x的根即可有两种方法:

    (1)非递归方法while(parent[x]>=0) x=parent[x];

    (2)递归方法:x为根时直接返回x,否则继续Find(parent[x])递归找x的父的根

    Union操作进行集合合并默认把元素Root2嫁接到Root1上parent[Root1]+=parent[Root2]; parent[Root2]=Root1;

    执行一次Union操作需要O(1)而n-1次Union操作可以在O(n)内完成

    性能不好,可能会产生退化了的树。此时Find操作需要从被搜索元素出发,沿父指针链走到根,完成Find(i)的时间复杂度为O(i)而完成n次搜索需要的总时间为O(n^2)

    可以使用加权规则得到改进Union操作,使用结点个数探查法求两个UFSets类集合的并,结点个数少的集合嫁接到结点个数多的集合上。执行一次WeightedUnion操作的时间比执行一次Union的时间稍多,但仍在常量界限O(1)范围内。

    折叠规则压缩路径的算法CollapsingFind:如果元素j是从元素i到根的路径上的一个结点,并且元素j的父结点不是根,则把元素j的父结点置为根

    const int DefaultSize=10;
    class UFSets{
    public:
        UFSets(int sz=DefaultSize);
        ~UfSets(){delete []parrent;}
        UFSets& operator=(UFSets& R);
        void Union(int Root1,int Root2);
        int Find(int x);   
        void WeightedUnion(int Root1,int Root2);
        int CollapsingFind(int i);
    private:
        int *parent;
        int size;
    }
    
    UFSets::UFSets(int sz){
        size=sz;
        parent=new int[size];
        for(int i=0;i<size;i++) parent[i]=-1;  //初始化时每个元素自成为单元素集合
    }
    
    int UFSets::Find(int x){
        //非递归方法,搜索并返回包含元素x的根
        while(parent[x]>=0) x=parent[x];
        return x;
        
        //  一种递归方法,x为根时直接返回x,否则递归找x的父的根
        //  if(parent[x]<0) return x;
        //  else return Find(parent[x]);
    }
    
    void UFSets::Union(int Root1,int Root2){
        parent[Root1]+=parent[Root2];
        parent[Root2]=Root1;
    }
    
    void UFSets::WeightedUnion(int Root1,int Root2){
        int r1=Find(Root1),r2=Find(Root2),temp;
        if(r1!=r2){
            temp=parent[r1]+parent[r2];
            if(parent[r2]<parent[r1]){  //r2结点个数更多
                parent[r1]=r2;
                parent[r2]=temp;
            }
            else{
                parent[r2]=r1;
                parent[r1]=temp;
            }
        }
    }
    
    int UFSets::CollapsingFind(int i){
        for(int j=i;parent[j]>=0;j=parent[j]);  //在包含i的树中搜索根j
        while(i!=j){         //将从j到根的路径上所有结点都变成根的子女
            int temp=parent[i];
            parent[i]=j;
            i=temp;
        }
        return j;
    }
  • 相关阅读:
    spin_count
    not in改写关联无需考虑重复数据
    substr函数
    Flex样式-ToolTip篇
    Flex样式-ProgressBar篇
    Flex样式-MenuBar篇
    Flex样式-DataGrid篇
    Flex样式-ColorPicker篇
    FireBug之Console命令大全
    Flex样式-VSlider篇
  • 原文地址:https://www.cnblogs.com/yangyuliufeng/p/9480051.html
Copyright © 2011-2022 走看看