zoukankan      html  css  js  c++  java
  • 并查集路径压缩与启发式合并

     

     

    〖程序清单〗

     

     

     

    初始化:

     

    for i:=1 to n do father[i]:=i;

     

    因为每个元素属于单独的一个集合,所以每个元素以自己作为根结点。

     

    寻找根结点编号并压缩路径:

     

    function getfather(v : integer) : integer;
    begin
    if father[v]=v then exit(v);
     father[v]:=getfather(father[v]);
     getfather:=father[v];
    end; 
    //合并两个集合: 
    proceudre merge(x, y : integer); 
    begin
    x:=getfather(x);
    y:=getfather(y); 
    father[x]:=y; 
    end;

     

    判断元素是否属于同一集合:

     

    function judge(x, y : integer) : boolean;
    begin 
    x:=getfaher(x);
    y:=gefather(y);
    if x=y then exit(true) else exit(false);
    end;

     

    这里有一个优化:让深度较小的树成为深度较大的树的子树,这样查找的次数就会少些。这个优化称为启发式合并。可以证明:这样做以后树的深度为O(logn)。即:在一个有n个元素的集合,我们将保证移动不超过logn次就可以找到目标。 

     

    function judge(x,y:integer):boolean; 
    
     var fx,fy : integer; 
    
      begin 
    
         fx := getfaher(x); 
    
         fy := gefather(y); 
    
         If fx=fy then  
    
           exit(true) else  
    
           judge := false; 
    
         if rank[fx]>rank[fy] then 
    
           father[fy] := fx else begin 
    
           father[fx] := fy; 
    
           if rank[fx]=rank[fy] then  
    
             inc(rank[fy]); 
    
         end; 
    
      end; 

    初始化:

    fillchar(rank,sizeof(rank),0);

     

     

    并查集的时间复杂度

     

    并查集进行n次查找的时间复杂度是O(n)

     

     

    它是阿克曼函数(Ackermann Function)的某个反函数。

    它可以看作是小于5的。所以可以认为并查集的时间复杂度几乎是线性的。

     

     

     

     

     

  • 相关阅读:
    关于docker remote api未授权访问漏洞的学习与研究
    c#调用 WinRAR.exe以命令行形式实现文件、文件夹的解压缩
    Redis作为多个Windows服务运行配置方法
    全景播放器-js+flash
    SQL 拼接多个字段的值&一个字段多条记录的拼接
    mysql-connector-java与mysql版本的对应
    Sass map详解
    情人节网站logo赏析
    表单标签动画畅想
    段落文字彩条效果
  • 原文地址:https://www.cnblogs.com/syzcannot/p/4072706.html
Copyright © 2011-2022 走看看